Skip to main content

thin_vec/
lib.rs

1#![deny(missing_docs)]
2
3//! `ThinVec` is exactly the same as `Vec`, except that it stores its `len` and `capacity` in the buffer
4//! it allocates.
5//!
6//! This makes the memory footprint of ThinVecs lower; notably in cases where space is reserved for
7//! a non-existence `ThinVec<T>`. So `Vec<ThinVec<T>>` and `Option<ThinVec<T>>::None` will waste less
8//! space. Being pointer-sized also means it can be passed/stored in registers.
9//!
10//! Of course, any actually constructed `ThinVec` will theoretically have a bigger allocation, but
11//! the fuzzy nature of allocators means that might not actually be the case.
12//!
13//! Properties of `Vec` that are preserved:
14//! * `ThinVec::new()` doesn't allocate (it points to a statically allocated singleton)
15//! * reallocation can be done in place
16//! * `size_of::<ThinVec<T>>()` == `size_of::<Option<ThinVec<T>>>()`
17//! * Doesn't allocate for Zero Sized Types (e.g. `ThinVec<()>`), but only without the "gecko-ffi" feature.
18//!
19//! Properties of `Vec` that aren't preserved:
20//! * `ThinVec<T>` can't ever be zero-cost roundtripped to a `Box<[T]>`, `String`, or `*mut T`
21//! * `from_raw_parts` doesn't exist
22//!
23//!
24//! # Optional Features
25//!
26//! # Gecko FFI
27//!
28//! If you enable the gecko-ffi feature, `ThinVec` will verbatim bridge with the nsTArray type in
29//! Gecko (Firefox). That is, `ThinVec` and nsTArray have identical layouts *but not ABIs*,
30//! so nsTArrays/ThinVecs an be natively manipulated by C++ and Rust, and ownership can be
31//! transferred across the FFI boundary (**IF YOU ARE CAREFUL, SEE BELOW!!**).
32//!
33//! While this feature is handy, it is also inherently dangerous to use because Rust and C++ do not
34//! know about each other. Specifically, this can be an issue with non-POD types (types which
35//! have destructors, move constructors, or are `!Copy`).
36//!
37//! ## Do Not Pass By Value
38//!
39//! The biggest thing to keep in mind is that **FFI functions cannot pass ThinVec/nsTArray
40//! by-value**. That is, these are busted APIs:
41//!
42//! ```rust,ignore
43//! // BAD WRONG
44//! extern fn process_data(data: ThinVec<u32>) { ... }
45//! // BAD WRONG
46//! extern fn get_data() -> ThinVec<u32> { ... }
47//! ```
48//!
49//! You must instead pass by-reference:
50//!
51//! ```rust
52//! # use thin_vec::*;
53//! # use std::mem;
54//!
55//! // Read-only access, ok!
56//! extern fn process_data(data: &ThinVec<u32>) {
57//!     for val in data {
58//!         println!("{}", val);
59//!     }
60//! }
61//!
62//! // Replace with empty instance to take ownership, ok!
63//! extern fn consume_data(data: &mut ThinVec<u32>) {
64//!     let owned = mem::replace(data, ThinVec::new());
65//!     mem::drop(owned);
66//! }
67//!
68//! // Mutate input, ok!
69//! extern fn add_data(dataset: &mut ThinVec<u32>) {
70//!     dataset.push(37);
71//!     dataset.push(12);
72//! }
73//!
74//! // Return via out-param, usually ok!
75//! //
76//! // WARNING: output must be initialized! (Empty nsTArrays are free, so just do it!)
77//! extern fn get_data(output: &mut ThinVec<u32>) {
78//!     *output = thin_vec![1, 2, 3, 4, 5];
79//! }
80//! ```
81//!
82//! Ignorable Explanation For Those Who Really Want To Know Why:
83//!
84//! > The fundamental issue is that Rust and C++ can't currently communicate about destructors, and
85//! > the semantics of C++ require destructors of function arguments to be run when the function
86//! > returns. Whether the callee or caller is responsible for this is also platform-specific, so
87//! > trying to hack around it manually would be messy.
88//! >
89//! > Also a type having a destructor changes its C++ ABI, because that type must actually exist
90//! > in memory (unlike a trivial struct, which is often passed in registers). We don't currently
91//! > have a way to communicate to Rust that this is happening, so even if we worked out the
92//! > destructor issue with say, MaybeUninit, it would still be a non-starter without some RFCs
93//! > to add explicit rustc support.
94//! >
95//! > Realistically, the best answer here is to have a "heavier" bindgen that can secretly
96//! > generate FFI glue so we can pass things "by value" and have it generate by-reference code
97//! > behind our back (like the cxx crate does). This would muddy up debugging/searchfox though.
98//!
99//! ## Types Should Be Trivially Relocatable
100//!
101//! Types in Rust are always trivially relocatable (unless suitably borrowed/[pinned][]/hidden).
102//! This means all Rust types are legal to relocate with a bitwise copy, you cannot provide
103//! copy or move constructors to execute when this happens, and the old location won't have its
104//! destructor run. This will cause problems for types which have a significant location
105//! (types that intrusively point into themselves or have their location registered with a service).
106//!
107//! While relocations are generally predictable if you're very careful, **you should avoid using
108//! types with significant locations with Rust FFI**.
109//!
110//! Specifically, `ThinVec` will trivially relocate its contents whenever it needs to reallocate its
111//! buffer to change its capacity. This is the default reallocation strategy for nsTArray, and is
112//! suitable for the vast majority of types. Just be aware of this limitation!
113//!
114//! ## Auto Arrays Are Dangerous
115//!
116//! `ThinVec` has *some* support for handling auto arrays which store their buffer on the stack,
117//! but this isn't well tested.
118//!
119//! Regardless of how much support we provide, Rust won't be aware of the buffer's limited lifetime,
120//! so standard auto array safety caveats apply about returning/storing them! `ThinVec` won't ever
121//! produce an auto array on its own, so this is only an issue for transferring an nsTArray into
122//! Rust.
123//!
124//! ## Other Issues
125//!
126//! Standard FFI caveats also apply:
127//!
128//!  * Rust is more strict about POD types being initialized (use MaybeUninit if you must)
129//!  * `ThinVec<T>` has no idea if the C++ version of `T` has move/copy/assign/delete overloads
130//!  * `nsTArray<T>` has no idea if the Rust version of `T` has a Drop/Clone impl
131//!  * C++ can do all sorts of unsound things that Rust can't catch
132//!  * C++ and Rust don't agree on how zero-sized/empty types should be handled
133//!
134//! The gecko-ffi feature will not work if you aren't linking with code that has nsTArray
135//! defined. Specifically, we must share the symbol for nsTArray's empty singleton. You will get
136//! linking errors if that isn't defined.
137//!
138//! The gecko-ffi feature also limits `ThinVec` to the legacy behaviors of nsTArray. Most notably,
139//! nsTArray has a maximum capacity of i32::MAX (~2.1 billion items). Probably not an issue.
140//! Probably.
141//!
142//! [pinned]: https://doc.rust-lang.org/std/pin/index.html
143
144#![cfg_attr(not(feature = "std"), no_std)]
145#![cfg_attr(feature = "unstable", feature(trusted_len))]
146#![cfg_attr(feature = "unstable", feature(dropck_eyepatch))]
147#![allow(clippy::comparison_chain, clippy::missing_safety_doc)]
148
149extern crate alloc;
150
151use alloc::alloc::*;
152use alloc::{boxed::Box, vec::Vec};
153use core::borrow::*;
154use core::cmp::*;
155use core::convert::TryFrom;
156use core::convert::TryInto;
157use core::hash::*;
158use core::iter::FromIterator;
159use core::marker::PhantomData;
160use core::ops::{Bound, Index, IndexMut};
161use core::ops::{Deref, DerefMut, RangeBounds};
162use core::ptr::NonNull;
163use core::slice::{Iter, SliceIndex};
164use core::{fmt, mem, ops, ptr, slice};
165
166use impl_details::*;
167
168#[cfg(feature = "malloc_size_of")]
169use malloc_size_of::{MallocShallowSizeOf, MallocSizeOf, MallocSizeOfOps};
170
171// modules: a simple way to cfg a whole bunch of impl details at once
172
173#[cfg(not(feature = "gecko-ffi"))]
174mod impl_details {
175    pub type SizeType = usize;
176    // for ZSTs, store the length in the the NonNull<T> as a NonZero<usize>,
177    // the length is thus off by one and can only reach usize::MAX - 1
178    pub const MAX_CAP: usize = usize::MAX - 1;
179
180    #[inline(always)]
181    pub fn assert_size(x: usize) -> SizeType {
182        x
183    }
184
185    #[inline(always)]
186    pub fn pack_capacity_and_auto(cap: SizeType, auto: bool) -> SizeType {
187        debug_assert!(!auto);
188        cap
189    }
190
191    #[inline(always)]
192    pub fn unpack_capacity(cap: SizeType) -> usize {
193        cap
194    }
195
196    #[inline(always)]
197    pub fn is_auto(_: SizeType) -> bool {
198        false
199    }
200}
201
202#[cfg(feature = "gecko-ffi")]
203mod impl_details {
204    // Support for briding a gecko nsTArray verbatim into a ThinVec.
205    //
206    // `ThinVec` can't see copy/move/delete implementations
207    // from C++
208    //
209    // The actual layout of an nsTArray is:
210    //
211    // ```cpp
212    // struct {
213    //   uint32_t mLength;
214    //   uint32_t mCapacity: 31;
215    //   uint32_t mIsAutoArray : 1;
216    // }
217    // ```
218    //
219    // Rust doesn't natively support bit-fields, so we manually mask
220    // and shift the bit. When the "auto" bit is set, the header and buffer
221    // are actually on the stack, meaning the `ThinVec` pointer-to-header
222    // is essentially an "owned borrow", and therefore dangerous to handle.
223    // There are no safety guards for this situation.
224    //
225    // On little-endian platforms, the auto bit will be the high-bit of
226    // our capacity u32. On big-endian platforms, it will be the low bit.
227    // Hence we need some platform-specific CFGs for the necessary masking/shifting.
228    //
229    // Handling the auto bit mostly just means not freeing/reallocating the buffer.
230
231    pub type SizeType = u32;
232
233    pub const MAX_CAP: usize = i32::MAX as usize;
234
235    // See kAutoTArrayHeaderOffset
236    pub const AUTO_ARRAY_HEADER_OFFSET: usize = 8;
237
238    // Little endian: the auto bit is the high bit, and the capacity is
239    // verbatim. So we just need to mask off the high bit. Note that
240    // this masking is unnecessary when packing, because assert_size
241    // guards against the high bit being set.
242    #[cfg(target_endian = "little")]
243    pub fn unpack_capacity(cap: SizeType) -> usize {
244        (cap as usize) & !(1 << 31)
245    }
246    #[cfg(target_endian = "little")]
247    pub fn is_auto(cap: SizeType) -> bool {
248        (cap & (1 << 31)) != 0
249    }
250    #[cfg(target_endian = "little")]
251    pub fn pack_capacity_and_auto(cap: SizeType, auto: bool) -> SizeType {
252        cap | ((auto as SizeType) << 31)
253    }
254
255    // Big endian: the auto bit is the low bit, and the capacity is
256    // shifted up one bit. Masking out the auto bit is unnecessary,
257    // as rust shifts always shift in 0's for unsigned integers.
258    #[cfg(target_endian = "big")]
259    pub fn unpack_capacity(cap: SizeType) -> usize {
260        (cap >> 1) as usize
261    }
262    #[cfg(target_endian = "big")]
263    pub fn is_auto(cap: SizeType) -> bool {
264        (cap & 1) != 0
265    }
266    #[cfg(target_endian = "big")]
267    pub fn pack_capacity_and_auto(cap: SizeType, auto: bool) -> SizeType {
268        (cap << 1) | (auto as SizeType)
269    }
270
271    #[inline]
272    pub fn assert_size(x: usize) -> SizeType {
273        if x > MAX_CAP as usize {
274            panic!("nsTArray size may not exceed the capacity of a 32-bit sized int");
275        }
276        x as SizeType
277    }
278}
279
280#[cold]
281fn capacity_overflow() -> ! {
282    panic!("capacity overflow")
283}
284
285trait UnwrapCapOverflow<T> {
286    fn unwrap_cap_overflow(self) -> T;
287}
288
289impl<T> UnwrapCapOverflow<T> for Option<T> {
290    fn unwrap_cap_overflow(self) -> T {
291        match self {
292            Some(val) => val,
293            None => capacity_overflow(),
294        }
295    }
296}
297
298impl<T, E> UnwrapCapOverflow<T> for Result<T, E> {
299    fn unwrap_cap_overflow(self) -> T {
300        match self {
301            Ok(val) => val,
302            Err(_) => capacity_overflow(),
303        }
304    }
305}
306
307// The header of a ThinVec.
308//
309// The _cap can be a bitfield, so use accessors to avoid trouble.
310//
311// In "real" gecko-ffi mode, the empty singleton will be aligned
312// to 8 by gecko. But in tests we have to provide the singleton
313// ourselves, and Rust makes it hard to "just" align a static.
314// To avoid messing around with a wrapper type around the
315// singleton *just* for tests, we just force all headers to be
316// aligned to 8 in this weird "zombie" gecko mode.
317//
318// This shouldn't affect runtime layout (padding), but it will
319// result in us asking the allocator to needlessly overalign
320// non-empty ThinVecs containing align < 8 types in
321// zombie-mode, but not in "real" geck-ffi mode. Minor.
322#[cfg_attr(all(feature = "gecko-ffi", any(test, miri)), repr(align(8)))]
323#[repr(C)]
324struct Header {
325    _len: SizeType,
326    _cap: SizeType,
327}
328
329impl Header {
330    #[inline]
331    #[allow(clippy::unnecessary_cast)]
332    fn len(&self) -> usize {
333        self._len as usize
334    }
335
336    #[inline]
337    fn set_len(&mut self, len: usize) {
338        self._len = assert_size(len);
339    }
340
341    fn cap(&self) -> usize {
342        unpack_capacity(self._cap)
343    }
344
345    fn set_cap_and_auto(&mut self, cap: usize, is_auto: bool) {
346        // debug check that our packing is working
347        debug_assert_eq!(
348            unpack_capacity(pack_capacity_and_auto(cap as SizeType, is_auto)),
349            cap
350        );
351        self._cap = pack_capacity_and_auto(assert_size(cap), is_auto);
352    }
353
354    #[inline]
355    fn is_auto(&self) -> bool {
356        is_auto(self._cap)
357    }
358}
359
360/// Singleton that all empty collections share.
361/// Note: can't store non-zero ZSTs, we allocate in that case. We could
362/// optimize everything to not do that (basically, make ptr == len and branch
363/// on size == 0 in every method), but it's a bunch of work for something that
364/// doesn't matter much.
365#[cfg(any(not(feature = "gecko-ffi"), test, miri))]
366static EMPTY_HEADER: Header = Header { _len: 0, _cap: 0 };
367
368#[cfg(all(feature = "gecko-ffi", not(test), not(miri)))]
369unsafe extern "C" {
370    #[link_name = "sEmptyTArrayHeader"]
371    static EMPTY_HEADER: Header;
372}
373
374// Utils for computing layouts of allocations
375
376/// Gets the size necessary to allocate a `ThinVec<T>` with the give capacity.
377///
378/// # Panics
379///
380/// This will panic if isize::MAX is overflowed at any point.
381fn alloc_size<T>(cap: usize) -> usize {
382    // Compute "real" header size with pointer math
383    //
384    // We turn everything into isizes here so that we can catch isize::MAX overflow,
385    // we never want to allow allocations larger than that!
386    let header_size = mem::size_of::<Header>() as isize;
387    let padding = padding::<T>() as isize;
388
389    let data_size = if mem::size_of::<T>() == 0 {
390        // If we're allocating an array for ZSTs we need a header/padding but no actual
391        // space for items, so we don't care about the capacity that was requested!
392        0
393    } else {
394        let cap: isize = cap.try_into().unwrap_cap_overflow();
395        let elem_size = mem::size_of::<T>() as isize;
396        elem_size.checked_mul(cap).unwrap_cap_overflow()
397    };
398
399    let final_size = data_size
400        .checked_add(header_size + padding)
401        .unwrap_cap_overflow();
402
403    // Ok now we can turn it back into a usize (don't need to worry about negatives)
404    final_size as usize
405}
406
407/// Gets the padding necessary for the array of a `ThinVec<T>`
408const fn padding<T>() -> usize {
409    let alloc_align = alloc_align::<T>();
410    let header_size = mem::size_of::<Header>();
411    if cfg!(feature = "gecko-ffi") {
412        assert!(
413            mem::size_of::<T>() != 0,
414            "ThinVec<T> cannot bridge to nsTArray<T> when T is zero-sized"
415        );
416        assert!(
417            header_size >= alloc_align,
418            "nsTArray does not handle alignment above the header size correctly",
419        );
420    }
421    alloc_align.saturating_sub(header_size)
422}
423
424/// Gets the align necessary to allocate a `ThinVec<T>`
425const fn alloc_align<T>() -> usize {
426    if mem::align_of::<T>() > mem::align_of::<Header>() {
427        return mem::align_of::<T>();
428    }
429    mem::align_of::<Header>()
430}
431
432/// Gets the layout necessary to allocate a `ThinVec<T>`
433///
434/// # Panics
435///
436/// Panics if the required size overflows `isize::MAX` when rounded up to the required alignment.
437fn layout<T>(cap: usize) -> Layout {
438    Layout::from_size_align(alloc_size::<T>(cap), alloc_align::<T>())
439        .ok()
440        .unwrap_cap_overflow()
441}
442
443/// Allocates a header (and array) for a `ThinVec<T>` with the given capacity.
444///
445/// # Panics
446///
447/// Panics if the required size overflows `isize::MAX` when rounded up to the required alignment.
448fn header_with_capacity<T>(cap: usize, is_auto: bool) -> NonNull<Header> {
449    debug_assert!(cap > 0);
450    unsafe {
451        let layout = layout::<T>(cap);
452        let header = alloc(layout) as *mut Header;
453
454        if header.is_null() {
455            handle_alloc_error(layout)
456        }
457
458        ptr::write(
459            header,
460            Header {
461                _len: 0,
462                _cap: if mem::size_of::<T>() == 0 {
463                    // "Infinite" capacity for zero-sized types:
464                    MAX_CAP as SizeType
465                } else {
466                    pack_capacity_and_auto(assert_size(cap), is_auto)
467                },
468            },
469        );
470
471        NonNull::new_unchecked(header)
472    }
473}
474
475/// # Safety
476///
477/// len must be != 0, this uses the `NonNull` to store a length, so the length must be stored offset by one.
478/// This function expect the len to be already shifted
479#[inline(always)]
480const unsafe fn len_to_ptr_unchecked<T: Sized>(len: usize) -> NonNull<T> {
481    use core::num::NonZeroUsize;
482    debug_assert!(len != 0);
483    // NonNull::without_provenance polyfill
484    unsafe { mem::transmute(NonZeroUsize::new_unchecked(len)) }
485}
486
487/// See the crate's top level documentation for a description of this type.
488#[repr(C)]
489pub struct ThinVec<T> {
490    ptr: NonNull<Header>,
491    boo: PhantomData<T>,
492}
493
494unsafe impl<T: Sync> Sync for ThinVec<T> {}
495unsafe impl<T: Send> Send for ThinVec<T> {}
496
497/// Creates a `ThinVec` containing the arguments.
498///
499// A hack to avoid linking problems with `cargo test --features=gecko-ffi`.
500#[cfg_attr(not(feature = "gecko-ffi"), doc = "```")]
501#[cfg_attr(feature = "gecko-ffi", doc = "```ignore")]
502/// #[macro_use] extern crate thin_vec;
503///
504/// fn main() {
505///     let v = thin_vec![1, 2, 3];
506///     assert_eq!(v.len(), 3);
507///     assert_eq!(v[0], 1);
508///     assert_eq!(v[1], 2);
509///     assert_eq!(v[2], 3);
510///
511///     let v = thin_vec![1; 3];
512///     assert_eq!(v, [1, 1, 1]);
513/// }
514/// ```
515#[macro_export]
516macro_rules! thin_vec {
517    (@UNIT $($t:tt)*) => (());
518
519    ($elem:expr; $n:expr) => ({
520        let mut vec = $crate::ThinVec::new();
521        vec.resize($n, $elem);
522        vec
523    });
524    () => {$crate::ThinVec::new()};
525    ($($x:expr),*) => ({
526        let len = [$($crate::thin_vec!(@UNIT $x)),*].len();
527        let mut vec = $crate::ThinVec::with_capacity(len);
528        $(vec.push($x);)*
529        vec
530    });
531    ($($x:expr,)*) => ($crate::thin_vec![$($x),*]);
532}
533
534impl<T> ThinVec<T> {
535    /// Return true if we can use ZST optimizations
536    #[inline(always)]
537    const fn is_zst() -> bool {
538        size_of::<T>() == 0 && !cfg!(feature = "gecko-ffi")
539    }
540
541    /// Creates a new empty ThinVec.
542    ///
543    /// This will not allocate.
544    pub const fn new() -> ThinVec<T> {
545        // See the comment in with_capacity().
546        let _ = padding::<T>();
547
548        if Self::is_zst() {
549            unsafe {
550                ThinVec {
551                    ptr: len_to_ptr_unchecked(1),
552                    boo: PhantomData,
553                }
554            }
555        } else {
556            unsafe {
557                ThinVec {
558                    ptr: NonNull::new_unchecked(&EMPTY_HEADER as *const Header as *mut Header),
559                    boo: PhantomData,
560                }
561            }
562        }
563    }
564
565    /// Constructs a new, empty `ThinVec<T>` with at least the specified capacity.
566    ///
567    /// The vector will be able to hold at least `capacity` elements without
568    /// reallocating. This method is allowed to allocate for more elements than
569    /// `capacity`. If `capacity` is 0, the vector will not allocate.
570    ///
571    /// It is important to note that although the returned vector has the
572    /// minimum *capacity* specified, the vector will have a zero *length*.
573    ///
574    /// If it is important to know the exact allocated capacity of a `ThinVec`,
575    /// always use the [`capacity`] method after construction.
576    ///
577    /// **NOTE**: like `Vec`, `ThinVec` doesn't allocate for ZSTs and stores the length inline,
578    /// but creating a `ThinVec` of ZSTs is not allowed if the "gecko-ffi" feature is enabled.
579    ///
580    /// [Capacity and reallocation]: #capacity-and-reallocation
581    /// [`capacity`]: Vec::capacity
582    ///
583    /// # Panics
584    ///
585    /// Panics if the new capacity exceeds `isize::MAX` bytes.
586    ///
587    /// # Examples
588    ///
589    /// ```
590    /// use thin_vec::ThinVec;
591    ///
592    /// let mut vec = ThinVec::with_capacity(10);
593    ///
594    /// // The vector contains no items, even though it has capacity for more
595    /// assert_eq!(vec.len(), 0);
596    /// assert!(vec.capacity() >= 10);
597    ///
598    /// // These are all done without reallocating...
599    /// for i in 0..10 {
600    ///     vec.push(i);
601    /// }
602    /// assert_eq!(vec.len(), 10);
603    /// assert!(vec.capacity() >= 10);
604    ///
605    /// // ...but this may make the vector reallocate
606    /// vec.push(11);
607    /// assert_eq!(vec.len(), 11);
608    /// assert!(vec.capacity() >= 11);
609    ///
610    /// # #[cfg(not(feature = "gecko-ffi"))] {
611    /// // A vector of a zero-sized type will not allocate and report to have max capacity.
612    /// // Note this is only true **without** the gecko-ffi feature!
613    /// let vec_units = ThinVec::<()>::with_capacity(10);
614    /// assert_eq!(vec_units.capacity(), usize::MAX - 1);
615    /// # }
616    /// ```
617    pub fn with_capacity(cap: usize) -> Self {
618        // `padding` contains ~static assertions against types that are
619        // incompatible with the current feature flags. We also call it to
620        // invoke these assertions when getting a pointer to the `ThinVec`
621        // contents, but since we also get a pointer to the contents in the
622        // `Drop` impl, tripping an assertion along that code path causes a
623        // double panic. We duplicate the assertion here so that it is
624        // testable,
625        let _ = padding::<T>();
626
627        if Self::is_zst() {
628            unsafe {
629                return ThinVec {
630                    ptr: len_to_ptr_unchecked(1),
631                    boo: PhantomData,
632                };
633            }
634        }
635
636        if cap == 0 {
637            return Self::new();
638        }
639        ThinVec {
640            ptr: header_with_capacity::<T>(cap, false),
641            boo: PhantomData,
642        }
643    }
644
645    // Accessor conveniences
646
647    /// # Safety
648    ///
649    /// must have Self::is_zst() == false
650    unsafe fn ptr(&self) -> *mut Header {
651        debug_assert!(!Self::is_zst());
652        self.ptr.as_ptr()
653    }
654
655    /// # Safety
656    ///
657    /// must have Self::is_zst() == false
658    unsafe fn header(&self) -> &Header {
659        debug_assert!(!Self::is_zst());
660        unsafe { self.ptr.as_ref() }
661    }
662
663    fn data_raw(&self) -> *mut T {
664        if Self::is_zst() {
665            return ptr::dangling_mut();
666        }
667
668        // `padding` contains ~static assertions against types that are
669        // incompatible with the current feature flags. Even if we don't
670        // care about its result, we should always call it before getting
671        // a data pointer to guard against invalid types!
672        let padding = padding::<T>();
673
674        // Although we ensure the data array is aligned when we allocate,
675        // we can't do that with the empty singleton. So when it might not
676        // be properly aligned, we substitute in the NonNull::dangling
677        // which *is* aligned.
678        //
679        // To minimize dynamic branches on `cap` for all accesses
680        // to the data, we include this guard which should only involve
681        // compile-time constants. Ideally this should result in the branch
682        // only be included for types with excessive alignment.
683        let empty_header_is_aligned = if cfg!(feature = "gecko-ffi") {
684            // in gecko-ffi mode `padding` will ensure this under
685            // the assumption that the header has size 8 and the
686            // static empty singleton is aligned to 8.
687            true
688        } else {
689            // In non-gecko-ffi mode, the empty singleton is just
690            // naturally aligned to the Header. If the Header is at
691            // least as aligned as T *and* the padding would have
692            // been 0, then one-past-the-end of the empty singleton
693            // *is* a valid data pointer and we can remove the
694            // `dangling` special case.
695            mem::align_of::<Header>() >= mem::align_of::<T>() && padding == 0
696        };
697
698        unsafe {
699            if !empty_header_is_aligned && self.header().cap() == 0 {
700                NonNull::dangling().as_ptr()
701            } else {
702                // This could technically result in overflow, but padding
703                // would have to be absurdly large for this to occur.
704                let header_size = mem::size_of::<Header>();
705                let ptr = self.ptr.as_ptr() as *mut u8;
706                ptr.add(header_size + padding) as *mut T
707            }
708        }
709    }
710
711    /// # Safety
712    ///
713    /// This is unsafe when the header is EMPTY_HEADER or when T is a ZST.
714    unsafe fn header_mut(&mut self) -> &mut Header {
715        debug_assert!(!self.is_singleton());
716        debug_assert!(!Self::is_zst());
717        unsafe { &mut *self.ptr() }
718    }
719
720    /// Returns the number of elements in the vector, also referred to
721    /// as its 'length'.
722    ///
723    /// # Examples
724    ///
725    /// ```
726    /// use thin_vec::thin_vec;
727    ///
728    /// let a = thin_vec![1, 2, 3];
729    /// assert_eq!(a.len(), 3);
730    /// ```
731    pub fn len(&self) -> usize {
732        if Self::is_zst() {
733            (self.ptr.as_ptr() as usize) - 1
734        } else {
735            unsafe { self.header().len() }
736        }
737    }
738
739    /// Returns `true` if the vector contains no elements.
740    ///
741    /// # Examples
742    ///
743    /// ```
744    /// use thin_vec::ThinVec;
745    ///
746    /// let mut v = ThinVec::new();
747    /// assert!(v.is_empty());
748    ///
749    /// v.push(1);
750    /// assert!(!v.is_empty());
751    /// ```
752    pub fn is_empty(&self) -> bool {
753        self.len() == 0
754    }
755
756    /// Returns the number of elements the vector can hold without
757    /// reallocating.
758    ///
759    /// # Examples
760    ///
761    /// ```
762    /// use thin_vec::ThinVec;
763    ///
764    /// let vec: ThinVec<i32> = ThinVec::with_capacity(10);
765    /// assert_eq!(vec.capacity(), 10);
766    /// ```
767    pub fn capacity(&self) -> usize {
768        if Self::is_zst() {
769            MAX_CAP
770        } else {
771            unsafe { self.header().cap() }
772        }
773    }
774
775    /// Returns `true` if the vector has the capacity to hold any element.
776    pub fn has_capacity(&self) -> bool {
777        !self.is_singleton()
778    }
779
780    /// Forces the length of the vector to `new_len`.
781    ///
782    /// This is a low-level operation that maintains none of the normal
783    /// invariants of the type. Normally changing the length of a vector
784    /// is done using one of the safe operations instead, such as
785    /// [`truncate`], [`resize`], [`extend`], or [`clear`].
786    ///
787    /// [`truncate`]: ThinVec::truncate
788    /// [`resize`]: ThinVec::resize
789    /// [`extend`]: ThinVec::extend
790    /// [`clear`]: ThinVec::clear
791    ///
792    /// # Safety
793    ///
794    /// - `new_len` must be less than or equal to [`capacity()`].
795    /// - The elements at `old_len..new_len` must be initialized.
796    ///
797    /// [`capacity()`]: ThinVec::capacity
798    ///
799    /// # Examples
800    ///
801    /// This method can be useful for situations in which the vector
802    /// is serving as a buffer for other code, particularly over FFI:
803    ///
804    /// ```no_run
805    /// use thin_vec::ThinVec;
806    ///
807    /// # // This is just a minimal skeleton for the doc example;
808    /// # // don't use this as a starting point for a real library.
809    /// # pub struct StreamWrapper { strm: *mut std::ffi::c_void }
810    /// # const Z_OK: i32 = 0;
811    /// # unsafe extern "C" {
812    /// #     fn deflateGetDictionary(
813    /// #         strm: *mut std::ffi::c_void,
814    /// #         dictionary: *mut u8,
815    /// #         dictLength: *mut usize,
816    /// #     ) -> i32;
817    /// # }
818    /// # impl StreamWrapper {
819    /// pub fn get_dictionary(&self) -> Option<ThinVec<u8>> {
820    ///     // Per the FFI method's docs, "32768 bytes is always enough".
821    ///     let mut dict = ThinVec::with_capacity(32_768);
822    ///     let mut dict_length = 0;
823    ///     // SAFETY: When `deflateGetDictionary` returns `Z_OK`, it holds that:
824    ///     // 1. `dict_length` elements were initialized.
825    ///     // 2. `dict_length` <= the capacity (32_768)
826    ///     // which makes `set_len` safe to call.
827    ///     unsafe {
828    ///         // Make the FFI call...
829    ///         let r = deflateGetDictionary(self.strm, dict.as_mut_ptr(), &mut dict_length);
830    ///         if r == Z_OK {
831    ///             // ...and update the length to what was initialized.
832    ///             dict.set_len(dict_length);
833    ///             Some(dict)
834    ///         } else {
835    ///             None
836    ///         }
837    ///     }
838    /// }
839    /// # }
840    /// ```
841    ///
842    /// While the following example is sound, there is a memory leak since
843    /// the inner vectors were not freed prior to the `set_len` call:
844    ///
845    /// ```no_run
846    /// use thin_vec::thin_vec;
847    ///
848    /// let mut vec = thin_vec![thin_vec![1, 0, 0],
849    ///                    thin_vec![0, 1, 0],
850    ///                    thin_vec![0, 0, 1]];
851    /// // SAFETY:
852    /// // 1. `old_len..0` is empty so no elements need to be initialized.
853    /// // 2. `0 <= capacity` always holds whatever `capacity` is.
854    /// unsafe {
855    ///     vec.set_len(0);
856    /// }
857    /// ```
858    ///
859    /// Normally, here, one would use [`clear`] instead to correctly drop
860    /// the contents and thus not leak memory.
861    pub unsafe fn set_len(&mut self, len: usize) {
862        if self.is_singleton() {
863            // A prerequisite of `Vec::set_len` is that `new_len` must be
864            // less than or equal to capacity(). The same applies here.
865            debug_assert!(len == 0, "invalid set_len({}) on empty ThinVec", len);
866        } else {
867            unsafe { self.set_len_non_singleton(len) }
868        }
869    }
870
871    /// For internal use only, when setting the length and it's known that T is a ZST.
872    /// # Safety
873    /// - This is unsafe when T is not a ZST.
874    /// - len must be < usize::MAX
875    #[inline]
876    unsafe fn set_len_zst(&mut self, len: usize) {
877        debug_assert!(Self::is_zst());
878        debug_assert!(
879            len <= MAX_CAP,
880            "invalid set_len(usize::MAX) on ZST ThinVec (max cap is usize::MAX - 1)"
881        );
882        unsafe { self.ptr = len_to_ptr_unchecked(len + 1) }
883    }
884
885    /// For internal use only, when setting the length and it's known that the header is owned.
886    /// # Safety
887    /// This is unsafe when the header is EMPTY_HEADER or when T is a ZST.
888    #[inline]
889    unsafe fn set_header_len(&mut self, len: usize) {
890        unsafe { self.header_mut().set_len(len) }
891    }
892
893    /// For internal use only, when setting the length and it's known to be the non-singleton or T is a ZST.
894    /// # Safety
895    /// This is unsafe when the header is EMPTY_HEADER.
896    #[inline(always)]
897    unsafe fn set_len_non_singleton(&mut self, len: usize) {
898        debug_assert!(!self.is_singleton());
899        if Self::is_zst() {
900            unsafe {
901                self.set_len_zst(len);
902            }
903        } else {
904            unsafe { self.set_header_len(len) }
905        }
906    }
907
908    /// Appends an element to the back of a collection.
909    ///
910    /// # Panics
911    ///
912    /// Panics if the new capacity exceeds `isize::MAX` bytes.
913    ///
914    /// # Examples
915    ///
916    /// ```
917    /// use thin_vec::thin_vec;
918    ///
919    /// let mut vec = thin_vec![1, 2];
920    /// vec.push(3);
921    /// assert_eq!(vec, [1, 2, 3]);
922    /// ```
923    pub fn push(&mut self, val: T) {
924        let old_len = self.len();
925        if old_len == self.capacity() {
926            self.reserve(1);
927        }
928        unsafe {
929            // SAFETY: reserve() ensures sufficient capacity.
930            self.push_unchecked(val);
931        }
932    }
933
934    /// Appends an element to the back like `push`,
935    /// but assumes that sufficient capacity has already been reserved, i.e.
936    /// `len() < capacity()`.
937    ///
938    /// # Safety
939    ///
940    /// - Capacity must be reserved in advance such that `capacity() > len()`.
941    #[inline]
942    unsafe fn push_unchecked(&mut self, val: T) {
943        let old_len = self.len();
944        debug_assert!(old_len < self.capacity());
945        unsafe {
946            ptr::write(self.data_raw().add(old_len), val);
947            // SAFETY: capacity > len >= 0, so capacity != 0, so this is not a singleton.
948            self.set_len_non_singleton(old_len + 1);
949        }
950    }
951
952    /// Removes the last element from a vector and returns it, or [`None`] if it
953    /// is empty.
954    ///
955    /// # Examples
956    ///
957    /// ```
958    /// use thin_vec::thin_vec;
959    ///
960    /// let mut vec = thin_vec![1, 2, 3];
961    /// assert_eq!(vec.pop(), Some(3));
962    /// assert_eq!(vec, [1, 2]);
963    /// ```
964    pub fn pop(&mut self) -> Option<T> {
965        let old_len = self.len();
966        if old_len == 0 {
967            return None;
968        }
969
970        unsafe {
971            self.set_len_non_singleton(old_len - 1);
972            Some(ptr::read(self.data_raw().add(old_len - 1)))
973        }
974    }
975
976    /// Inserts an element at position `index` within the vector, shifting all
977    /// elements after it to the right.
978    ///
979    /// # Panics
980    ///
981    /// Panics if `index > len`.
982    ///
983    /// # Examples
984    ///
985    /// ```
986    /// use thin_vec::thin_vec;
987    ///
988    /// let mut vec = thin_vec![1, 2, 3];
989    /// vec.insert(1, 4);
990    /// assert_eq!(vec, [1, 4, 2, 3]);
991    /// vec.insert(4, 5);
992    /// assert_eq!(vec, [1, 4, 2, 3, 5]);
993    /// ```
994    pub fn insert(&mut self, idx: usize, elem: T) {
995        let old_len = self.len();
996
997        assert!(idx <= old_len, "Index out of bounds");
998        if old_len == self.capacity() {
999            self.reserve(1);
1000        }
1001        unsafe {
1002            let ptr = self.data_raw();
1003            ptr::copy(ptr.add(idx), ptr.add(idx + 1), old_len - idx);
1004            ptr::write(ptr.add(idx), elem);
1005            self.set_header_len(old_len + 1);
1006        }
1007    }
1008
1009    /// Removes and returns the element at position `index` within the vector,
1010    /// shifting all elements after it to the left.
1011    ///
1012    /// Note: Because this shifts over the remaining elements, it has a
1013    /// worst-case performance of *O*(*n*). If you don't need the order of elements
1014    /// to be preserved, use [`swap_remove`] instead. If you'd like to remove
1015    /// elements from the beginning of the `ThinVec`, consider using `std::collections::VecDeque`.
1016    ///
1017    /// [`swap_remove`]: ThinVec::swap_remove
1018    ///
1019    /// # Panics
1020    ///
1021    /// Panics if `index` is out of bounds.
1022    ///
1023    /// # Examples
1024    ///
1025    /// ```
1026    /// use thin_vec::thin_vec;
1027    ///
1028    /// let mut v = thin_vec![1, 2, 3];
1029    /// assert_eq!(v.remove(1), 2);
1030    /// assert_eq!(v, [1, 3]);
1031    /// ```
1032    pub fn remove(&mut self, idx: usize) -> T {
1033        let old_len = self.len();
1034
1035        assert!(idx < old_len, "Index out of bounds");
1036
1037        unsafe {
1038            self.set_len_non_singleton(old_len - 1);
1039            let ptr = self.data_raw();
1040            let val = ptr::read(self.data_raw().add(idx));
1041            ptr::copy(ptr.add(idx + 1), ptr.add(idx), old_len - idx - 1);
1042            val
1043        }
1044    }
1045
1046    /// Removes an element from the vector and returns it.
1047    ///
1048    /// The removed element is replaced by the last element of the vector.
1049    ///
1050    /// This does not preserve ordering, but is *O*(1).
1051    /// If you need to preserve the element order, use [`remove`] instead.
1052    ///
1053    /// [`remove`]: ThinVec::remove
1054    ///
1055    /// # Panics
1056    ///
1057    /// Panics if `index` is out of bounds.
1058    ///
1059    /// # Examples
1060    ///
1061    /// ```
1062    /// use thin_vec::thin_vec;
1063    ///
1064    /// let mut v = thin_vec!["foo", "bar", "baz", "qux"];
1065    ///
1066    /// assert_eq!(v.swap_remove(1), "bar");
1067    /// assert_eq!(v, ["foo", "qux", "baz"]);
1068    ///
1069    /// assert_eq!(v.swap_remove(0), "foo");
1070    /// assert_eq!(v, ["baz", "qux"]);
1071    /// ```
1072    pub fn swap_remove(&mut self, idx: usize) -> T {
1073        let old_len = self.len();
1074
1075        assert!(idx < old_len, "Index out of bounds");
1076
1077        unsafe {
1078            let ptr = self.data_raw();
1079            ptr::swap(ptr.add(idx), ptr.add(old_len - 1));
1080            self.set_len_non_singleton(old_len - 1);
1081            ptr::read(ptr.add(old_len - 1))
1082        }
1083    }
1084
1085    /// Shortens the vector, keeping the first `len` elements and dropping
1086    /// the rest.
1087    ///
1088    /// If `len` is greater than the vector's current length, this has no
1089    /// effect.
1090    ///
1091    /// The [`drain`] method can emulate `truncate`, but causes the excess
1092    /// elements to be returned instead of dropped.
1093    ///
1094    /// Note that this method has no effect on the allocated capacity
1095    /// of the vector.
1096    ///
1097    /// # Examples
1098    ///
1099    /// Truncating a five element vector to two elements:
1100    ///
1101    /// ```
1102    /// use thin_vec::thin_vec;
1103    ///
1104    /// let mut vec = thin_vec![1, 2, 3, 4, 5];
1105    /// vec.truncate(2);
1106    /// assert_eq!(vec, [1, 2]);
1107    /// ```
1108    ///
1109    /// No truncation occurs when `len` is greater than the vector's current
1110    /// length:
1111    ///
1112    /// ```
1113    /// use thin_vec::thin_vec;
1114    ///
1115    /// let mut vec = thin_vec![1, 2, 3];
1116    /// vec.truncate(8);
1117    /// assert_eq!(vec, [1, 2, 3]);
1118    /// ```
1119    ///
1120    /// Truncating when `len == 0` is equivalent to calling the [`clear`]
1121    /// method.
1122    ///
1123    /// ```
1124    /// use thin_vec::thin_vec;
1125    ///
1126    /// let mut vec = thin_vec![1, 2, 3];
1127    /// vec.truncate(0);
1128    /// assert_eq!(vec, []);
1129    /// ```
1130    ///
1131    /// [`clear`]: ThinVec::clear
1132    /// [`drain`]: ThinVec::drain
1133    pub fn truncate(&mut self, len: usize) {
1134        unsafe {
1135            // drop any extra elements
1136            while len < self.len() {
1137                // decrement len before the drop_in_place(), so a panic on Drop
1138                // doesn't re-drop the just-failed value.
1139                let new_len = self.len() - 1;
1140                self.set_len_non_singleton(new_len);
1141                let ptr = self.data_raw().add(new_len);
1142                ptr::drop_in_place(ptr);
1143            }
1144        }
1145    }
1146
1147    /// Clears the vector, removing all values.
1148    ///
1149    /// Note that this method has no effect on the allocated capacity
1150    /// of the vector.
1151    ///
1152    /// # Examples
1153    ///
1154    /// ```
1155    /// use thin_vec::thin_vec;
1156    ///
1157    /// let mut v = thin_vec![1, 2, 3];
1158    /// v.clear();
1159    /// assert!(v.is_empty());
1160    /// ```
1161    pub fn clear(&mut self) {
1162        unsafe {
1163            // Decrement len even in the case of a panic.
1164            struct DropGuard<'a, T>(&'a mut ThinVec<T>);
1165            impl<T> Drop for DropGuard<'_, T> {
1166                fn drop(&mut self) {
1167                    unsafe {
1168                        // Could be the singleton.
1169                        self.0.set_len(0);
1170                    }
1171                }
1172            }
1173            let guard = DropGuard(self);
1174            ptr::drop_in_place(&mut guard.0[..]);
1175        }
1176    }
1177
1178    /// Extracts a slice containing the entire vector.
1179    ///
1180    /// Equivalent to `&s[..]`.
1181    ///
1182    /// # Examples
1183    ///
1184    /// ```
1185    /// use thin_vec::thin_vec;
1186    /// use std::io::{self, Write};
1187    /// let buffer = thin_vec![1, 2, 3, 5, 8];
1188    /// io::sink().write(buffer.as_slice()).unwrap();
1189    /// ```
1190    pub fn as_slice(&self) -> &[T] {
1191        unsafe { slice::from_raw_parts(self.data_raw(), self.len()) }
1192    }
1193
1194    /// Extracts a mutable slice of the entire vector.
1195    ///
1196    /// Equivalent to `&mut s[..]`.
1197    ///
1198    /// # Examples
1199    ///
1200    /// ```
1201    /// use thin_vec::thin_vec;
1202    /// use std::io::{self, Read};
1203    /// let mut buffer = vec![0; 3];
1204    /// io::repeat(0b101).read_exact(buffer.as_mut_slice()).unwrap();
1205    /// ```
1206    pub fn as_mut_slice(&mut self) -> &mut [T] {
1207        unsafe { slice::from_raw_parts_mut(self.data_raw(), self.len()) }
1208    }
1209
1210    /// Reserve capacity for at least `additional` more elements to be inserted.
1211    ///
1212    /// May reserve more space than requested, to avoid frequent reallocations.
1213    ///
1214    /// Panics if the new capacity overflows `usize`.
1215    ///
1216    /// Re-allocates only if `self.capacity() < self.len() + additional`.
1217    #[cfg(not(feature = "gecko-ffi"))]
1218    pub fn reserve(&mut self, additional: usize) {
1219        let len = self.len();
1220        let old_cap = self.capacity();
1221        let min_cap = len.checked_add(additional).unwrap_cap_overflow();
1222        if min_cap <= old_cap {
1223            return;
1224        }
1225        // only way to get here is if min_cap == usize::MAX, which we can't handle.
1226        if Self::is_zst() {
1227            capacity_overflow();
1228        }
1229        // Ensure the new capacity is at least double, to guarantee exponential growth.
1230        let double_cap = if old_cap == 0 {
1231            // skip to 4 because tiny ThinVecs are dumb; but not if that would cause overflow
1232            if mem::size_of::<T>() > (!0) / 8 { 1 } else { 4 }
1233        } else {
1234            old_cap.saturating_mul(2)
1235        };
1236        let new_cap = max(min_cap, double_cap);
1237        unsafe {
1238            self.reallocate(new_cap);
1239        }
1240    }
1241
1242    /// Reserve capacity for at least `additional` more elements to be inserted.
1243    ///
1244    /// This method mimics the growth algorithm used by the C++ implementation
1245    /// of nsTArray.
1246    #[cfg(feature = "gecko-ffi")]
1247    pub fn reserve(&mut self, additional: usize) {
1248        let elem_size = mem::size_of::<T>();
1249
1250        let len = self.len();
1251        let old_cap = self.capacity();
1252        let min_cap = len.checked_add(additional).unwrap_cap_overflow();
1253        if min_cap <= old_cap {
1254            return;
1255        }
1256        // The growth logic can't handle zero-sized types, so we have to exit
1257        // early here.
1258        if elem_size == 0 {
1259            unsafe {
1260                self.reallocate(min_cap);
1261            }
1262            return;
1263        }
1264
1265        let min_cap_bytes = assert_size(min_cap)
1266            .checked_mul(assert_size(elem_size))
1267            .and_then(|x| x.checked_add(assert_size(mem::size_of::<Header>())))
1268            .unwrap();
1269
1270        // Perform some checked arithmetic to ensure all of the numbers we
1271        // compute will end up in range.
1272        let will_fit = min_cap_bytes.checked_mul(2).is_some();
1273        if !will_fit {
1274            panic!("Exceeded maximum nsTArray size");
1275        }
1276
1277        const SLOW_GROWTH_THRESHOLD: usize = 8 * 1024 * 1024;
1278
1279        let bytes = if min_cap > SLOW_GROWTH_THRESHOLD {
1280            // Grow by a minimum of 1.125x
1281            let old_cap_bytes = old_cap * elem_size + mem::size_of::<Header>();
1282            let min_growth = old_cap_bytes + (old_cap_bytes >> 3);
1283            let growth = max(min_growth, min_cap_bytes as usize);
1284
1285            // Round up to the next megabyte.
1286            const MB: usize = 1 << 20;
1287            MB * ((growth + MB - 1) / MB)
1288        } else {
1289            // Try to allocate backing buffers in powers of two.
1290            min_cap_bytes.next_power_of_two() as usize
1291        };
1292
1293        let cap = (bytes - core::mem::size_of::<Header>()) / elem_size;
1294        unsafe {
1295            self.reallocate(cap);
1296        }
1297    }
1298
1299    /// Reserves the minimum capacity for `additional` more elements to be inserted.
1300    ///
1301    /// Panics if the new capacity overflows `usize`.
1302    ///
1303    /// Re-allocates only if `self.capacity() < self.len() + additional`.
1304    pub fn reserve_exact(&mut self, additional: usize) {
1305        let new_cap = self.len().checked_add(additional).unwrap_cap_overflow();
1306        let old_cap = self.capacity();
1307        if new_cap > old_cap {
1308            // only way to get here is if new_cap == usize::MAX, which we can't handle.
1309            if Self::is_zst() {
1310                capacity_overflow()
1311            }
1312            unsafe {
1313                self.reallocate(new_cap);
1314            }
1315        }
1316    }
1317
1318    /// Shrinks the capacity of the vector as much as possible.
1319    ///
1320    /// It will drop down as close as possible to the length but the allocator
1321    /// may still inform the vector that there is space for a few more elements.
1322    ///
1323    /// # Examples
1324    ///
1325    /// ```
1326    /// use thin_vec::ThinVec;
1327    ///
1328    /// let mut vec = ThinVec::with_capacity(10);
1329    /// vec.extend([1, 2, 3]);
1330    /// assert_eq!(vec.capacity(), 10);
1331    /// vec.shrink_to_fit();
1332    /// assert!(vec.capacity() >= 3);
1333    /// ```
1334    pub fn shrink_to_fit(&mut self) {
1335        if Self::is_zst() {
1336            return;
1337        }
1338        let old_cap = self.capacity();
1339        let new_cap = self.len();
1340        if new_cap >= old_cap {
1341            return;
1342        }
1343        #[cfg(feature = "gecko-ffi")]
1344        unsafe {
1345            let stack_buf = self.auto_array_header_mut();
1346            if !stack_buf.is_null() && (*stack_buf).cap() >= new_cap {
1347                // Try to switch to our auto-buffer.
1348                if stack_buf == self.ptr.as_ptr() {
1349                    return;
1350                }
1351                stack_buf
1352                    .add(1)
1353                    .cast::<T>()
1354                    .copy_from_nonoverlapping(self.data_raw(), new_cap);
1355                dealloc(self.ptr() as *mut u8, layout::<T>(old_cap));
1356                self.ptr = NonNull::new_unchecked(stack_buf);
1357                self.ptr.as_mut().set_len(new_cap);
1358                return;
1359            }
1360        }
1361        if new_cap == 0 {
1362            *self = ThinVec::new();
1363        } else {
1364            unsafe {
1365                self.reallocate(new_cap);
1366            }
1367        }
1368    }
1369
1370    /// Retains only the elements specified by the predicate.
1371    ///
1372    /// In other words, remove all elements `e` such that `f(&e)` returns `false`.
1373    /// This method operates in place and preserves the order of the retained
1374    /// elements.
1375    ///
1376    /// # Examples
1377    ///
1378    // A hack to avoid linking problems with `cargo test --features=gecko-ffi`.
1379    #[cfg_attr(not(feature = "gecko-ffi"), doc = "```")]
1380    #[cfg_attr(feature = "gecko-ffi", doc = "```ignore")]
1381    /// # #[macro_use] extern crate thin_vec;
1382    /// # fn main() {
1383    /// let mut vec = thin_vec![1, 2, 3, 4];
1384    /// vec.retain(|&x| x%2 == 0);
1385    /// assert_eq!(vec, [2, 4]);
1386    /// # }
1387    /// ```
1388    pub fn retain<F>(&mut self, mut f: F)
1389    where
1390        F: FnMut(&T) -> bool,
1391    {
1392        self.retain_mut(|x| f(&*x));
1393    }
1394
1395    /// Retains only the elements specified by the predicate, passing a mutable reference to it.
1396    ///
1397    /// In other words, remove all elements `e` such that `f(&mut e)` returns `false`.
1398    /// This method operates in place and preserves the order of the retained
1399    /// elements.
1400    ///
1401    /// # Examples
1402    ///
1403    // A hack to avoid linking problems with `cargo test --features=gecko-ffi`.
1404    #[cfg_attr(not(feature = "gecko-ffi"), doc = "```")]
1405    #[cfg_attr(feature = "gecko-ffi", doc = "```ignore")]
1406    /// # #[macro_use] extern crate thin_vec;
1407    /// # fn main() {
1408    /// let mut vec = thin_vec![1, 2, 3, 4, 5];
1409    /// vec.retain_mut(|x| {
1410    ///     *x += 1;
1411    ///     (*x)%2 == 0
1412    /// });
1413    /// assert_eq!(vec, [2, 4, 6]);
1414    /// # }
1415    /// ```
1416    pub fn retain_mut<F>(&mut self, mut f: F)
1417    where
1418        F: FnMut(&mut T) -> bool,
1419    {
1420        let len = self.len();
1421        let mut del = 0;
1422        {
1423            let v = &mut self[..];
1424
1425            for i in 0..len {
1426                if !f(&mut v[i]) {
1427                    del += 1;
1428                } else if del > 0 {
1429                    v.swap(i - del, i);
1430                }
1431            }
1432        }
1433        if del > 0 {
1434            self.truncate(len - del);
1435        }
1436    }
1437
1438    /// Removes consecutive elements in the vector that resolve to the same key.
1439    ///
1440    /// If the vector is sorted, this removes all duplicates.
1441    ///
1442    /// # Examples
1443    ///
1444    // A hack to avoid linking problems with `cargo test --features=gecko-ffi`.
1445    #[cfg_attr(not(feature = "gecko-ffi"), doc = "```")]
1446    #[cfg_attr(feature = "gecko-ffi", doc = "```ignore")]
1447    /// # #[macro_use] extern crate thin_vec;
1448    /// # fn main() {
1449    /// let mut vec = thin_vec![10, 20, 21, 30, 20];
1450    ///
1451    /// vec.dedup_by_key(|i| *i / 10);
1452    ///
1453    /// assert_eq!(vec, [10, 20, 30, 20]);
1454    /// # }
1455    /// ```
1456    pub fn dedup_by_key<F, K>(&mut self, mut key: F)
1457    where
1458        F: FnMut(&mut T) -> K,
1459        K: PartialEq<K>,
1460    {
1461        self.dedup_by(|a, b| key(a) == key(b))
1462    }
1463
1464    /// Removes consecutive elements in the vector according to a predicate.
1465    ///
1466    /// The `same_bucket` function is passed references to two elements from the vector, and
1467    /// returns `true` if the elements compare equal, or `false` if they do not. Only the first
1468    /// of adjacent equal items is kept.
1469    ///
1470    /// If the vector is sorted, this removes all duplicates.
1471    ///
1472    /// # Examples
1473    ///
1474    // A hack to avoid linking problems with `cargo test --features=gecko-ffi`.
1475    #[cfg_attr(not(feature = "gecko-ffi"), doc = "```")]
1476    #[cfg_attr(feature = "gecko-ffi", doc = "```ignore")]
1477    /// # #[macro_use] extern crate thin_vec;
1478    /// # fn main() {
1479    /// let mut vec = thin_vec!["foo", "bar", "Bar", "baz", "bar"];
1480    ///
1481    /// vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
1482    ///
1483    /// assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
1484    /// # }
1485    /// ```
1486    #[allow(clippy::swap_ptr_to_ref)]
1487    pub fn dedup_by<F>(&mut self, mut same_bucket: F)
1488    where
1489        F: FnMut(&mut T, &mut T) -> bool,
1490    {
1491        // See the comments in `Vec::dedup` for a detailed explanation of this code.
1492        unsafe {
1493            let ln = self.len();
1494            if ln <= 1 {
1495                return;
1496            }
1497
1498            // Avoid bounds checks by using raw pointers.
1499            let p = self.as_mut_ptr();
1500            let mut r: usize = 1;
1501            let mut w: usize = 1;
1502
1503            while r < ln {
1504                let p_r = p.add(r);
1505                let p_wm1 = p.add(w - 1);
1506                if !same_bucket(&mut *p_r, &mut *p_wm1) {
1507                    if r != w {
1508                        let p_w = p_wm1.add(1);
1509                        mem::swap(&mut *p_r, &mut *p_w);
1510                    }
1511                    w += 1;
1512                }
1513                r += 1;
1514            }
1515
1516            self.truncate(w);
1517        }
1518    }
1519
1520    /// Splits the collection into two at the given index.
1521    ///
1522    /// Returns a newly allocated vector containing the elements in the range
1523    /// `[at, len)`. After the call, the original vector will be left containing
1524    /// the elements `[0, at)` with its previous capacity unchanged.
1525    ///
1526    /// # Panics
1527    ///
1528    /// Panics if `at > len`.
1529    ///
1530    /// # Examples
1531    ///
1532    /// ```
1533    /// use thin_vec::thin_vec;
1534    ///
1535    /// let mut vec = thin_vec![1, 2, 3];
1536    /// let vec2 = vec.split_off(1);
1537    /// assert_eq!(vec, [1]);
1538    /// assert_eq!(vec2, [2, 3]);
1539    /// ```
1540    pub fn split_off(&mut self, at: usize) -> ThinVec<T> {
1541        let old_len = self.len();
1542        let new_vec_len = old_len - at;
1543
1544        assert!(at <= old_len, "Index out of bounds");
1545
1546        unsafe {
1547            let mut new_vec = ThinVec::with_capacity(new_vec_len);
1548
1549            ptr::copy_nonoverlapping(self.data_raw().add(at), new_vec.data_raw(), new_vec_len);
1550
1551            new_vec.set_len(new_vec_len); // could be the singleton
1552            self.set_len(at); // could be the singleton
1553
1554            new_vec
1555        }
1556    }
1557
1558    /// Moves all the elements of `other` into `self`, leaving `other` empty.
1559    ///
1560    /// # Panics
1561    ///
1562    /// Panics if the new capacity exceeds `isize::MAX` bytes.
1563    ///
1564    /// # Examples
1565    ///
1566    /// ```
1567    /// use thin_vec::thin_vec;
1568    ///
1569    /// let mut vec = thin_vec![1, 2, 3];
1570    /// let mut vec2 = thin_vec![4, 5, 6];
1571    /// vec.append(&mut vec2);
1572    /// assert_eq!(vec, [1, 2, 3, 4, 5, 6]);
1573    /// assert_eq!(vec2, []);
1574    /// ```
1575    pub fn append(&mut self, other: &mut ThinVec<T>) {
1576        self.extend(other.drain(..))
1577    }
1578
1579    /// Removes the specified range from the vector in bulk, returning all
1580    /// removed elements as an iterator. If the iterator is dropped before
1581    /// being fully consumed, it drops the remaining removed elements.
1582    ///
1583    /// The returned iterator keeps a mutable borrow on the vector to optimize
1584    /// its implementation.
1585    ///
1586    /// # Panics
1587    ///
1588    /// Panics if the starting point is greater than the end point or if
1589    /// the end point is greater than the length of the vector.
1590    ///
1591    /// # Leaking
1592    ///
1593    /// If the returned iterator goes out of scope without being dropped (due to
1594    /// [`mem::forget`], for example), the vector may have lost and leaked
1595    /// elements arbitrarily, including elements outside the range.
1596    ///
1597    /// # Examples
1598    ///
1599    /// ```
1600    /// use thin_vec::{ThinVec, thin_vec};
1601    ///
1602    /// let mut v = thin_vec![1, 2, 3];
1603    /// let u: ThinVec<_> = v.drain(1..).collect();
1604    /// assert_eq!(v, &[1]);
1605    /// assert_eq!(u, &[2, 3]);
1606    ///
1607    /// // A full range clears the vector, like `clear()` does
1608    /// v.drain(..);
1609    /// assert_eq!(v, &[]);
1610    /// ```
1611    pub fn drain<R>(&mut self, range: R) -> Drain<'_, T>
1612    where
1613        R: RangeBounds<usize>,
1614    {
1615        // See comments in the Drain struct itself for details on this
1616        let len = self.len();
1617        let start = match range.start_bound() {
1618            Bound::Included(&n) => n,
1619            Bound::Excluded(&n) => n + 1,
1620            Bound::Unbounded => 0,
1621        };
1622        let end = match range.end_bound() {
1623            Bound::Included(&n) => n + 1,
1624            Bound::Excluded(&n) => n,
1625            Bound::Unbounded => len,
1626        };
1627        assert!(start <= end);
1628        assert!(end <= len);
1629
1630        unsafe {
1631            // Set our length to the start bound
1632            self.set_len(start); // could be the singleton
1633
1634            let iter = slice::from_raw_parts(self.data_raw().add(start), end - start).iter();
1635
1636            Drain {
1637                iter,
1638                vec: NonNull::from(self),
1639                end,
1640                tail: len - end,
1641            }
1642        }
1643    }
1644
1645    /// Creates a splicing iterator that replaces the specified range in the vector
1646    /// with the given `replace_with` iterator and yields the removed items.
1647    /// `replace_with` does not need to be the same length as `range`.
1648    ///
1649    /// `range` is removed even if the iterator is not consumed until the end.
1650    ///
1651    /// It is unspecified how many elements are removed from the vector
1652    /// if the `Splice` value is leaked.
1653    ///
1654    /// The input iterator `replace_with` is only consumed when the `Splice` value is dropped.
1655    ///
1656    /// This is optimal if:
1657    ///
1658    /// * The tail (elements in the vector after `range`) is empty,
1659    /// * or `replace_with` yields fewer or equal elements than `range`’s length
1660    /// * or the lower bound of its `size_hint()` is exact.
1661    ///
1662    /// Otherwise, a temporary vector is allocated and the tail is moved twice.
1663    ///
1664    /// # Panics
1665    ///
1666    /// Panics if the starting point is greater than the end point or if
1667    /// the end point is greater than the length of the vector.
1668    ///
1669    /// # Examples
1670    ///
1671    /// ```
1672    /// use thin_vec::{ThinVec, thin_vec};
1673    ///
1674    /// let mut v = thin_vec![1, 2, 3, 4];
1675    /// let new = [7, 8, 9];
1676    /// let u: ThinVec<_> = v.splice(1..3, new).collect();
1677    /// assert_eq!(v, &[1, 7, 8, 9, 4]);
1678    /// assert_eq!(u, &[2, 3]);
1679    /// ```
1680    #[inline]
1681    pub fn splice<R, I>(&mut self, range: R, replace_with: I) -> Splice<'_, I::IntoIter>
1682    where
1683        R: RangeBounds<usize>,
1684        I: IntoIterator<Item = T>,
1685    {
1686        Splice {
1687            drain: self.drain(range),
1688            replace_with: replace_with.into_iter(),
1689        }
1690    }
1691
1692    /// Creates an iterator which uses a closure to determine if an element should be removed.
1693    ///
1694    /// If the closure returns true, then the element is removed and yielded.
1695    /// If the closure returns false, the element will remain in the vector and will not be yielded
1696    /// by the iterator.
1697    ///
1698    /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
1699    /// or the iteration short-circuits, then the remaining elements will be retained.
1700    /// Use [`ThinVec::retain`] with a negated predicate if you do not need the returned iterator.
1701    ///
1702    /// Using this method is equivalent to the following code:
1703    ///
1704    /// ```
1705    /// # use thin_vec::{ThinVec, thin_vec};
1706    /// # let some_predicate = |x: &mut i32| { *x == 2 || *x == 3 || *x == 6 };
1707    /// # let mut vec = thin_vec![1, 2, 3, 4, 5, 6];
1708    /// let mut i = 0;
1709    /// while i < vec.len() {
1710    ///     if some_predicate(&mut vec[i]) {
1711    ///         let val = vec.remove(i);
1712    ///         // your code here
1713    ///     } else {
1714    ///         i += 1;
1715    ///     }
1716    /// }
1717    ///
1718    /// # assert_eq!(vec, thin_vec![1, 4, 5]);
1719    /// ```
1720    ///
1721    /// But `extract_if` is easier to use. `extract_if` is also more efficient,
1722    /// because it can backshift the elements of the array in bulk.
1723    ///
1724    /// Note that `extract_if` also lets you mutate every element in the filter closure,
1725    /// regardless of whether you choose to keep or remove it.
1726    ///
1727    /// # Examples
1728    ///
1729    /// Splitting an array into evens and odds, reusing the original allocation:
1730    ///
1731    /// ```
1732    /// use thin_vec::{ThinVec, thin_vec};
1733    ///
1734    /// let mut numbers = thin_vec![1, 2, 3, 4, 5, 6, 8, 9, 11, 13, 14, 15];
1735    ///
1736    /// let evens = numbers.extract_if(.., |x| *x % 2 == 0).collect::<ThinVec<_>>();
1737    /// let odds = numbers;
1738    ///
1739    /// assert_eq!(evens, thin_vec![2, 4, 6, 8, 14]);
1740    /// assert_eq!(odds, thin_vec![1, 3, 5, 9, 11, 13, 15]);
1741    /// ```
1742    pub fn extract_if<F, R: RangeBounds<usize>>(
1743        &mut self,
1744        range: R,
1745        filter: F,
1746    ) -> ExtractIf<'_, T, F>
1747    where
1748        F: FnMut(&mut T) -> bool,
1749    {
1750        // Copy of https://github.com/rust-lang/rust/blob/ee361e8fca1c30e13e7a31cc82b64c045339d3a8/library/core/src/slice/index.rs#L37
1751        fn slice_index_fail(start: usize, end: usize, len: usize) -> ! {
1752            if start > len {
1753                panic!(
1754                    "range start index {} out of range for slice of length {}",
1755                    start, len
1756                )
1757            }
1758
1759            if end > len {
1760                panic!(
1761                    "range end index {} out of range for slice of length {}",
1762                    end, len
1763                )
1764            }
1765
1766            if start > end {
1767                panic!("slice index starts at {} but ends at {}", start, end)
1768            }
1769
1770            // Only reachable if the range was a `RangeInclusive` or a
1771            // `RangeToInclusive`, with `end == len`.
1772            panic!(
1773                "range end index {} out of range for slice of length {}",
1774                end, len
1775            )
1776        }
1777
1778        // Backport of https://github.com/rust-lang/rust/blob/ee361e8fca1c30e13e7a31cc82b64c045339d3a8/library/core/src/slice/index.rs#L855
1779        pub fn slice_range<R>(range: R, bounds: ops::RangeTo<usize>) -> ops::Range<usize>
1780        where
1781            R: ops::RangeBounds<usize>,
1782        {
1783            let len = bounds.end;
1784
1785            let end = match range.end_bound() {
1786                ops::Bound::Included(&end) if end >= len => slice_index_fail(0, end, len),
1787                // Cannot overflow because `end < len` implies `end < usize::MAX`.
1788                ops::Bound::Included(&end) => end + 1,
1789
1790                ops::Bound::Excluded(&end) if end > len => slice_index_fail(0, end, len),
1791                ops::Bound::Excluded(&end) => end,
1792                ops::Bound::Unbounded => len,
1793            };
1794
1795            let start = match range.start_bound() {
1796                ops::Bound::Excluded(&start) if start >= end => slice_index_fail(start, end, len),
1797                // Cannot overflow because `start < end` implies `start < usize::MAX`.
1798                ops::Bound::Excluded(&start) => start + 1,
1799
1800                ops::Bound::Included(&start) if start > end => slice_index_fail(start, end, len),
1801                ops::Bound::Included(&start) => start,
1802
1803                ops::Bound::Unbounded => 0,
1804            };
1805
1806            ops::Range { start, end }
1807        }
1808
1809        let old_len = self.len();
1810        let ops::Range { start, end } = slice_range(range, ..old_len);
1811
1812        // Guard against the vec getting leaked (leak amplification)
1813        unsafe {
1814            self.set_len(0);
1815        }
1816        ExtractIf {
1817            vec: self,
1818            idx: start,
1819            del: 0,
1820            end,
1821            old_len,
1822            pred: filter,
1823        }
1824    }
1825
1826    /// Resize the buffer and update its capacity, without changing the length.
1827    /// Unsafe because it can cause length to be greater than capacity.
1828    ///
1829    /// # Safety
1830    ///
1831    /// Must not be called if Self::is_zst()
1832    unsafe fn reallocate(&mut self, new_cap: usize) {
1833        debug_assert!(new_cap > 0);
1834        debug_assert!(!Self::is_zst());
1835        if self.has_allocation() {
1836            let old_cap = self.capacity();
1837            unsafe {
1838                let ptr = realloc(
1839                    self.ptr() as *mut u8,
1840                    layout::<T>(old_cap),
1841                    alloc_size::<T>(new_cap),
1842                ) as *mut Header;
1843                if ptr.is_null() {
1844                    handle_alloc_error(layout::<T>(new_cap))
1845                }
1846                (*ptr).set_cap_and_auto(new_cap, (*ptr).is_auto());
1847                self.ptr = NonNull::new_unchecked(ptr);
1848            }
1849        } else {
1850            let mut new_header = header_with_capacity::<T>(new_cap, self.is_auto_array());
1851
1852            // If we get here and have a non-zero len, then we must be handling
1853            // a gecko auto array, and we have items in a stack buffer. We shouldn't
1854            // free it, but we should memcopy the contents out of it and mark it as empty.
1855            //
1856            // T is assumed to be trivially relocatable, as this is ~required
1857            // for Rust compatibility anyway. Furthermore, we assume C++ won't try
1858            // to unconditionally destroy the contents of the stack allocated buffer
1859            // (i.e. it's obfuscated behind a union).
1860            //
1861            // In effect, we are partially reimplementing the auto array move constructor
1862            // by leaving behind a valid empty instance.
1863            let len = self.len();
1864            if cfg!(feature = "gecko-ffi") && len > 0 {
1865                unsafe {
1866                    new_header
1867                        .as_ptr()
1868                        .add(1)
1869                        .cast::<T>()
1870                        .copy_from_nonoverlapping(self.data_raw(), len);
1871                    self.set_header_len(0);
1872                    new_header.as_mut().set_len(len);
1873                }
1874            }
1875
1876            self.ptr = new_header;
1877        }
1878    }
1879
1880    #[inline]
1881    #[allow(unused_unsafe)]
1882    fn is_singleton(&self) -> bool {
1883        if Self::is_zst() {
1884            false
1885        } else {
1886            unsafe { self.ptr.as_ptr() as *const Header == &EMPTY_HEADER }
1887        }
1888    }
1889
1890    #[cfg(feature = "gecko-ffi")]
1891    #[inline]
1892    fn auto_array_header_mut(&mut self) -> *mut Header {
1893        if !self.is_auto_array() {
1894            return ptr::null_mut();
1895        }
1896        unsafe { (self as *mut Self).byte_add(AUTO_ARRAY_HEADER_OFFSET) as *mut Header }
1897    }
1898
1899    #[cfg(feature = "gecko-ffi")]
1900    #[inline]
1901    fn auto_array_header(&self) -> *const Header {
1902        if !self.is_auto_array() {
1903            return ptr::null_mut();
1904        }
1905        unsafe { (self as *const Self).byte_add(AUTO_ARRAY_HEADER_OFFSET) as *const Header }
1906    }
1907
1908    #[inline]
1909    fn is_auto_array(&self) -> bool {
1910        unsafe { self.ptr.as_ref().is_auto() }
1911    }
1912
1913    #[inline]
1914    fn uses_stack_allocated_buffer(&self) -> bool {
1915        #[cfg(feature = "gecko-ffi")]
1916        return self.auto_array_header() == self.ptr.as_ptr();
1917        #[cfg(not(feature = "gecko-ffi"))]
1918        return false;
1919    }
1920
1921    #[inline]
1922    fn has_allocation(&self) -> bool {
1923        !Self::is_zst() && !self.is_singleton() && !self.uses_stack_allocated_buffer()
1924    }
1925}
1926
1927impl<T: Clone> ThinVec<T> {
1928    /// Resizes the `Vec` in-place so that `len()` is equal to `new_len`.
1929    ///
1930    /// If `new_len` is greater than `len()`, the `Vec` is extended by the
1931    /// difference, with each additional slot filled with `value`.
1932    /// If `new_len` is less than `len()`, the `Vec` is simply truncated.
1933    ///
1934    /// # Examples
1935    ///
1936    // A hack to avoid linking problems with `cargo test --features=gecko-ffi`.
1937    #[cfg_attr(not(feature = "gecko-ffi"), doc = "```")]
1938    #[cfg_attr(feature = "gecko-ffi", doc = "```ignore")]
1939    /// # #[macro_use] extern crate thin_vec;
1940    /// # fn main() {
1941    /// let mut vec = thin_vec!["hello"];
1942    /// vec.resize(3, "world");
1943    /// assert_eq!(vec, ["hello", "world", "world"]);
1944    ///
1945    /// let mut vec = thin_vec![1, 2, 3, 4];
1946    /// vec.resize(2, 0);
1947    /// assert_eq!(vec, [1, 2]);
1948    /// # }
1949    /// ```
1950    pub fn resize(&mut self, new_len: usize, value: T) {
1951        let old_len = self.len();
1952
1953        if new_len > old_len {
1954            let additional = new_len - old_len;
1955            self.reserve(additional);
1956            for _ in 1..additional {
1957                self.push(value.clone());
1958            }
1959            // We can write the last element directly without cloning needlessly
1960            if additional > 0 {
1961                self.push(value);
1962            }
1963        } else if new_len < old_len {
1964            self.truncate(new_len);
1965        }
1966    }
1967
1968    /// Clones and appends all elements in a slice to the `ThinVec`.
1969    ///
1970    /// Iterates over the slice `other`, clones each element, and then appends
1971    /// it to this `ThinVec`. The `other` slice is traversed in-order.
1972    ///
1973    /// Note that this function is same as [`extend`] except that it is
1974    /// specialized to work with slices instead. If and when Rust gets
1975    /// specialization this function will likely be deprecated (but still
1976    /// available).
1977    ///
1978    /// # Examples
1979    ///
1980    /// ```
1981    /// use thin_vec::thin_vec;
1982    ///
1983    /// let mut vec = thin_vec![1];
1984    /// vec.extend_from_slice(&[2, 3, 4]);
1985    /// assert_eq!(vec, [1, 2, 3, 4]);
1986    /// ```
1987    ///
1988    /// [`extend`]: ThinVec::extend
1989    pub fn extend_from_slice(&mut self, other: &[T]) {
1990        self.extend(other.iter().cloned())
1991    }
1992}
1993
1994impl<T: PartialEq> ThinVec<T> {
1995    /// Removes consecutive repeated elements in the vector.
1996    ///
1997    /// If the vector is sorted, this removes all duplicates.
1998    ///
1999    /// # Examples
2000    ///
2001    // A hack to avoid linking problems with `cargo test --features=gecko-ffi`.
2002    #[cfg_attr(not(feature = "gecko-ffi"), doc = "```")]
2003    #[cfg_attr(feature = "gecko-ffi", doc = "```ignore")]
2004    /// # #[macro_use] extern crate thin_vec;
2005    /// # fn main() {
2006    /// let mut vec = thin_vec![1, 2, 2, 3, 2];
2007    ///
2008    /// vec.dedup();
2009    ///
2010    /// assert_eq!(vec, [1, 2, 3, 2]);
2011    /// # }
2012    /// ```
2013    pub fn dedup(&mut self) {
2014        self.dedup_by(|a, b| a == b)
2015    }
2016}
2017
2018#[cold]
2019#[inline(never)]
2020fn drop_non_singleton<T>(this: &mut ThinVec<T>) {
2021    unsafe {
2022        ptr::drop_in_place(&mut this[..]);
2023
2024        if this.uses_stack_allocated_buffer() {
2025            return;
2026        }
2027
2028        dealloc(this.ptr() as *mut u8, layout::<T>(this.capacity()))
2029    }
2030}
2031
2032/// # Safety
2033///
2034/// This function drop and deallocates the inner values of the `ThinVec`,
2035/// invariants are therefore broken and the value must be considered dropped and should not be accessed again.
2036#[inline]
2037unsafe fn drop_thin_vec<T>(this: &mut ThinVec<T>) {
2038    if ThinVec::<T>::is_zst() {
2039        unsafe {
2040            ptr::drop_in_place(&mut this[..]);
2041        }
2042    } else if !this.is_singleton() {
2043        drop_non_singleton(this);
2044    }
2045}
2046
2047#[cfg(not(feature = "unstable"))]
2048impl<T> Drop for ThinVec<T> {
2049    #[inline]
2050    fn drop(&mut self) {
2051        unsafe {
2052            drop_thin_vec(self);
2053        }
2054    }
2055}
2056
2057#[cfg(feature = "unstable")]
2058unsafe impl<#[may_dangle] T> Drop for ThinVec<T> {
2059    #[inline]
2060    fn drop(&mut self) {
2061        unsafe {
2062            drop_thin_vec(self);
2063        }
2064    }
2065}
2066
2067impl<T> Deref for ThinVec<T> {
2068    type Target = [T];
2069
2070    fn deref(&self) -> &[T] {
2071        self.as_slice()
2072    }
2073}
2074
2075impl<T> DerefMut for ThinVec<T> {
2076    fn deref_mut(&mut self) -> &mut [T] {
2077        self.as_mut_slice()
2078    }
2079}
2080
2081impl<T, I: SliceIndex<[T]>> Index<I> for ThinVec<T> {
2082    type Output = <I as SliceIndex<[T]>>::Output;
2083
2084    fn index(&self, index: I) -> &Self::Output {
2085        &self.deref()[index]
2086    }
2087}
2088
2089impl<T, I: SliceIndex<[T]>> IndexMut<I> for ThinVec<T> {
2090    fn index_mut(&mut self, index: I) -> &mut Self::Output {
2091        &mut self.deref_mut()[index]
2092    }
2093}
2094
2095impl<T> Borrow<[T]> for ThinVec<T> {
2096    fn borrow(&self) -> &[T] {
2097        self.as_slice()
2098    }
2099}
2100
2101impl<T> BorrowMut<[T]> for ThinVec<T> {
2102    fn borrow_mut(&mut self) -> &mut [T] {
2103        self.as_mut_slice()
2104    }
2105}
2106
2107impl<T> AsRef<[T]> for ThinVec<T> {
2108    fn as_ref(&self) -> &[T] {
2109        self.as_slice()
2110    }
2111}
2112
2113impl<T> Extend<T> for ThinVec<T> {
2114    #[inline]
2115    fn extend<I>(&mut self, iter: I)
2116    where
2117        I: IntoIterator<Item = T>,
2118    {
2119        let mut iter = iter.into_iter();
2120        let hint = iter.size_hint().0;
2121        if hint > 0 {
2122            self.reserve(hint);
2123            for x in iter.by_ref().take(hint) {
2124                // SAFETY: `reserve(hint)` ensures the next `hint` calls of `push_unchecked`
2125                // have sufficient capacity.
2126                unsafe {
2127                    self.push_unchecked(x);
2128                }
2129            }
2130        }
2131
2132        // if the hint underestimated the iterator length,
2133        // push the remaining items with capacity check each time.
2134        for x in iter {
2135            self.push(x);
2136        }
2137    }
2138}
2139
2140impl<T: fmt::Debug> fmt::Debug for ThinVec<T> {
2141    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2142        fmt::Debug::fmt(&**self, f)
2143    }
2144}
2145
2146impl<T> Hash for ThinVec<T>
2147where
2148    T: Hash,
2149{
2150    fn hash<H>(&self, state: &mut H)
2151    where
2152        H: Hasher,
2153    {
2154        self[..].hash(state);
2155    }
2156}
2157
2158impl<T> PartialOrd for ThinVec<T>
2159where
2160    T: PartialOrd,
2161{
2162    #[inline]
2163    fn partial_cmp(&self, other: &ThinVec<T>) -> Option<Ordering> {
2164        self[..].partial_cmp(&other[..])
2165    }
2166}
2167
2168impl<T> Ord for ThinVec<T>
2169where
2170    T: Ord,
2171{
2172    #[inline]
2173    fn cmp(&self, other: &ThinVec<T>) -> Ordering {
2174        self[..].cmp(&other[..])
2175    }
2176}
2177
2178impl<A, B> PartialEq<ThinVec<B>> for ThinVec<A>
2179where
2180    A: PartialEq<B>,
2181{
2182    #[inline]
2183    fn eq(&self, other: &ThinVec<B>) -> bool {
2184        self[..] == other[..]
2185    }
2186}
2187
2188impl<A, B> PartialEq<Vec<B>> for ThinVec<A>
2189where
2190    A: PartialEq<B>,
2191{
2192    #[inline]
2193    fn eq(&self, other: &Vec<B>) -> bool {
2194        self[..] == other[..]
2195    }
2196}
2197
2198impl<A, B> PartialEq<[B]> for ThinVec<A>
2199where
2200    A: PartialEq<B>,
2201{
2202    #[inline]
2203    fn eq(&self, other: &[B]) -> bool {
2204        self[..] == other[..]
2205    }
2206}
2207
2208impl<'a, A, B> PartialEq<&'a [B]> for ThinVec<A>
2209where
2210    A: PartialEq<B>,
2211{
2212    #[inline]
2213    fn eq(&self, other: &&'a [B]) -> bool {
2214        self[..] == other[..]
2215    }
2216}
2217
2218// Serde impls based on
2219// https://github.com/bluss/arrayvec/blob/67ec907a98c0f40c4b76066fed3c1af59d35cf6a/src/arrayvec.rs#L1222-L1267
2220#[cfg(feature = "serde")]
2221impl<T: serde::Serialize> serde::Serialize for ThinVec<T> {
2222    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
2223    where
2224        S: serde::Serializer,
2225    {
2226        serializer.collect_seq(self.as_slice())
2227    }
2228}
2229
2230#[cfg(feature = "serde")]
2231impl<'de, T: serde::Deserialize<'de>> serde::Deserialize<'de> for ThinVec<T> {
2232    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
2233    where
2234        D: serde::Deserializer<'de>,
2235    {
2236        use serde::Deserialize;
2237        use serde::de::{SeqAccess, Visitor};
2238
2239        struct ThinVecVisitor<T>(PhantomData<T>);
2240
2241        impl<'de, T: Deserialize<'de>> Visitor<'de> for ThinVecVisitor<T> {
2242            type Value = ThinVec<T>;
2243
2244            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
2245                write!(formatter, "a sequence")
2246            }
2247
2248            fn visit_seq<SA>(self, mut seq: SA) -> Result<Self::Value, SA::Error>
2249            where
2250                SA: SeqAccess<'de>,
2251            {
2252                // Same policy as
2253                // https://github.com/serde-rs/serde/blob/ce0844b9ecc32377b5e4545d759d385a8c46bc6a/serde/src/private/size_hint.rs#L13
2254                let initial_capacity = seq.size_hint().unwrap_or_default().min(4096);
2255                let mut values = ThinVec::<T>::with_capacity(initial_capacity);
2256
2257                while let Some(value) = seq.next_element()? {
2258                    values.push(value);
2259                }
2260
2261                Ok(values)
2262            }
2263        }
2264
2265        deserializer.deserialize_seq(ThinVecVisitor::<T>(PhantomData))
2266    }
2267}
2268
2269#[cfg(feature = "malloc_size_of")]
2270impl<T> MallocShallowSizeOf for ThinVec<T> {
2271    fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
2272        if !self.has_allocation() {
2273            // We're not a heap pointer.
2274            return 0;
2275        }
2276
2277        unsafe { ops.malloc_size_of(self.ptr() as _) }
2278    }
2279}
2280
2281#[cfg(feature = "malloc_size_of")]
2282impl<T: MallocSizeOf> MallocSizeOf for ThinVec<T> {
2283    fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
2284        let mut n = self.shallow_size_of(ops);
2285        for elem in self.iter() {
2286            n += elem.size_of(ops);
2287        }
2288        n
2289    }
2290}
2291
2292macro_rules! array_impls {
2293    ($($N:expr)*) => {$(
2294        impl<A, B> PartialEq<[B; $N]> for ThinVec<A> where A: PartialEq<B> {
2295            #[inline]
2296            fn eq(&self, other: &[B; $N]) -> bool { self[..] == other[..] }
2297        }
2298
2299        impl<'a, A, B> PartialEq<&'a [B; $N]> for ThinVec<A> where A: PartialEq<B> {
2300            #[inline]
2301            fn eq(&self, other: &&'a [B; $N]) -> bool { self[..] == other[..] }
2302        }
2303    )*}
2304}
2305
2306array_impls! {
2307    0  1  2  3  4  5  6  7  8  9
2308    10 11 12 13 14 15 16 17 18 19
2309    20 21 22 23 24 25 26 27 28 29
2310    30 31 32
2311}
2312
2313impl<T> Eq for ThinVec<T> where T: Eq {}
2314
2315impl<T> IntoIterator for ThinVec<T> {
2316    type Item = T;
2317    type IntoIter = IntoIter<T>;
2318
2319    fn into_iter(self) -> IntoIter<T> {
2320        IntoIter {
2321            vec: self,
2322            start: 0,
2323        }
2324    }
2325}
2326
2327impl<'a, T> IntoIterator for &'a ThinVec<T> {
2328    type Item = &'a T;
2329    type IntoIter = slice::Iter<'a, T>;
2330
2331    fn into_iter(self) -> slice::Iter<'a, T> {
2332        self.iter()
2333    }
2334}
2335
2336impl<'a, T> IntoIterator for &'a mut ThinVec<T> {
2337    type Item = &'a mut T;
2338    type IntoIter = slice::IterMut<'a, T>;
2339
2340    fn into_iter(self) -> slice::IterMut<'a, T> {
2341        self.iter_mut()
2342    }
2343}
2344
2345impl<T> Clone for ThinVec<T>
2346where
2347    T: Clone,
2348{
2349    #[inline]
2350    fn clone(&self) -> ThinVec<T> {
2351        #[cold]
2352        #[inline(never)]
2353        fn clone_non_singleton<T: Clone>(this: &ThinVec<T>) -> ThinVec<T> {
2354            let len = this.len();
2355            let mut new_vec = ThinVec::<T>::with_capacity(len);
2356            let mut data_raw = new_vec.data_raw();
2357            for x in this.iter() {
2358                unsafe {
2359                    ptr::write(data_raw, x.clone());
2360                    data_raw = data_raw.add(1);
2361                }
2362            }
2363            unsafe {
2364                // `this` is not the singleton, but `new_vec` will be if
2365                // `this` is empty.
2366                new_vec.set_len(len); // could be the singleton
2367            }
2368            new_vec
2369        }
2370
2371        if self.is_singleton() {
2372            ThinVec::new()
2373        } else {
2374            clone_non_singleton(self)
2375        }
2376    }
2377}
2378
2379impl<T> Default for ThinVec<T> {
2380    fn default() -> ThinVec<T> {
2381        ThinVec::new()
2382    }
2383}
2384
2385impl<T> FromIterator<T> for ThinVec<T> {
2386    #[inline]
2387    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> ThinVec<T> {
2388        let iter = iter.into_iter();
2389        let mut vec = ThinVec::with_capacity(iter.size_hint().0);
2390        vec.extend(iter);
2391        vec
2392    }
2393}
2394
2395impl<T: Clone> From<&[T]> for ThinVec<T> {
2396    /// Allocate a `ThinVec<T>` and fill it by cloning `s`'s items.
2397    ///
2398    /// # Examples
2399    ///
2400    /// ```
2401    /// use thin_vec::{ThinVec, thin_vec};
2402    ///
2403    /// assert_eq!(ThinVec::from(&[1, 2, 3][..]), thin_vec![1, 2, 3]);
2404    /// ```
2405    fn from(s: &[T]) -> ThinVec<T> {
2406        s.iter().cloned().collect()
2407    }
2408}
2409
2410impl<T: Clone> From<&mut [T]> for ThinVec<T> {
2411    /// Allocate a `ThinVec<T>` and fill it by cloning `s`'s items.
2412    ///
2413    /// # Examples
2414    ///
2415    /// ```
2416    /// use thin_vec::{ThinVec, thin_vec};
2417    ///
2418    /// assert_eq!(ThinVec::from(&mut [1, 2, 3][..]), thin_vec![1, 2, 3]);
2419    /// ```
2420    fn from(s: &mut [T]) -> ThinVec<T> {
2421        s.iter().cloned().collect()
2422    }
2423}
2424
2425impl<T, const N: usize> From<[T; N]> for ThinVec<T> {
2426    /// Allocate a `ThinVec<T>` and move `s`'s items into it.
2427    ///
2428    /// # Examples
2429    ///
2430    /// ```
2431    /// use thin_vec::{ThinVec, thin_vec};
2432    ///
2433    /// assert_eq!(ThinVec::from([1, 2, 3]), thin_vec![1, 2, 3]);
2434    /// ```
2435    fn from(s: [T; N]) -> ThinVec<T> {
2436        core::iter::IntoIterator::into_iter(s).collect()
2437    }
2438}
2439
2440impl<T> From<Box<[T]>> for ThinVec<T> {
2441    /// Convert a boxed slice into a vector by transferring ownership of
2442    /// the existing heap allocation.
2443    ///
2444    /// **NOTE:** unlike `std`, this must reallocate to change the layout!
2445    ///
2446    /// # Examples
2447    ///
2448    /// ```
2449    /// use thin_vec::{ThinVec, thin_vec};
2450    ///
2451    /// let b: Box<[i32]> = thin_vec![1, 2, 3].into_iter().collect();
2452    /// assert_eq!(ThinVec::from(b), thin_vec![1, 2, 3]);
2453    /// ```
2454    fn from(s: Box<[T]>) -> Self {
2455        // Can just lean on the fact that `Box<[T]>` -> `Vec<T>` is Free.
2456        Vec::from(s).into_iter().collect()
2457    }
2458}
2459
2460impl<T> From<Vec<T>> for ThinVec<T> {
2461    /// Convert a `std::Vec` into a `ThinVec`.
2462    ///
2463    /// **NOTE:** this must reallocate to change the layout!
2464    ///
2465    /// # Examples
2466    ///
2467    /// ```
2468    /// use thin_vec::{ThinVec, thin_vec};
2469    ///
2470    /// let b: Vec<i32> = vec![1, 2, 3];
2471    /// assert_eq!(ThinVec::from(b), thin_vec![1, 2, 3]);
2472    /// ```
2473    fn from(s: Vec<T>) -> Self {
2474        s.into_iter().collect()
2475    }
2476}
2477
2478impl<T> From<ThinVec<T>> for Vec<T> {
2479    /// Convert a `ThinVec` into a `std::Vec`.
2480    ///
2481    /// **NOTE:** this must reallocate to change the layout!
2482    ///
2483    /// # Examples
2484    ///
2485    /// ```
2486    /// use thin_vec::{ThinVec, thin_vec};
2487    ///
2488    /// let b: ThinVec<i32> = thin_vec![1, 2, 3];
2489    /// assert_eq!(Vec::from(b), vec![1, 2, 3]);
2490    /// ```
2491    fn from(s: ThinVec<T>) -> Self {
2492        s.into_iter().collect()
2493    }
2494}
2495
2496impl<T> From<ThinVec<T>> for Box<[T]> {
2497    /// Convert a vector into a boxed slice.
2498    ///
2499    /// If `v` has excess capacity, its items will be moved into a
2500    /// newly-allocated buffer with exactly the right capacity.
2501    ///
2502    /// **NOTE:** unlike `std`, this must reallocate to change the layout!
2503    ///
2504    /// # Examples
2505    ///
2506    /// ```
2507    /// use thin_vec::{ThinVec, thin_vec};
2508    /// assert_eq!(Box::from(thin_vec![1, 2, 3]), thin_vec![1, 2, 3].into_iter().collect());
2509    /// ```
2510    fn from(v: ThinVec<T>) -> Self {
2511        v.into_iter().collect()
2512    }
2513}
2514
2515impl From<&str> for ThinVec<u8> {
2516    /// Allocate a `ThinVec<u8>` and fill it with a UTF-8 string.
2517    ///
2518    /// # Examples
2519    ///
2520    /// ```
2521    /// use thin_vec::{ThinVec, thin_vec};
2522    ///
2523    /// assert_eq!(ThinVec::from("123"), thin_vec![b'1', b'2', b'3']);
2524    /// ```
2525    fn from(s: &str) -> ThinVec<u8> {
2526        From::from(s.as_bytes())
2527    }
2528}
2529
2530impl<T, const N: usize> TryFrom<ThinVec<T>> for [T; N] {
2531    type Error = ThinVec<T>;
2532
2533    /// Gets the entire contents of the `ThinVec<T>` as an array,
2534    /// if its size exactly matches that of the requested array.
2535    ///
2536    /// # Examples
2537    ///
2538    /// ```
2539    /// use thin_vec::{ThinVec, thin_vec};
2540    /// use std::convert::TryInto;
2541    ///
2542    /// assert_eq!(thin_vec![1, 2, 3].try_into(), Ok([1, 2, 3]));
2543    /// assert_eq!(<ThinVec<i32>>::new().try_into(), Ok([]));
2544    /// ```
2545    ///
2546    /// If the length doesn't match, the input comes back in `Err`:
2547    /// ```
2548    /// use thin_vec::{ThinVec, thin_vec};
2549    /// use std::convert::TryInto;
2550    ///
2551    /// let r: Result<[i32; 4], _> = (0..10).collect::<ThinVec<_>>().try_into();
2552    /// assert_eq!(r, Err(thin_vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]));
2553    /// ```
2554    ///
2555    /// If you're fine with just getting a prefix of the `ThinVec<T>`,
2556    /// you can call [`.truncate(N)`](ThinVec::truncate) first.
2557    /// ```
2558    /// use thin_vec::{ThinVec, thin_vec};
2559    /// use std::convert::TryInto;
2560    ///
2561    /// let mut v = ThinVec::from("hello world");
2562    /// v.sort();
2563    /// v.truncate(2);
2564    /// let [a, b]: [_; 2] = v.try_into().unwrap();
2565    /// assert_eq!(a, b' ');
2566    /// assert_eq!(b, b'd');
2567    /// ```
2568    fn try_from(mut vec: ThinVec<T>) -> Result<[T; N], ThinVec<T>> {
2569        if vec.len() != N {
2570            return Err(vec);
2571        }
2572
2573        // SAFETY: `.set_len(0)` is always sound.
2574        unsafe { vec.set_len(0) };
2575
2576        // SAFETY: A `ThinVec`'s pointer is always aligned properly, and
2577        // the alignment the array needs is the same as the items.
2578        // We checked earlier that we have sufficient items.
2579        // The items will not double-drop as the `set_len`
2580        // tells the `ThinVec` not to also drop them.
2581        let array = unsafe { ptr::read(vec.data_raw() as *const [T; N]) };
2582        Ok(array)
2583    }
2584}
2585
2586/// An iterator that moves out of a vector.
2587///
2588/// This `struct` is created by the [`ThinVec::into_iter`][]
2589/// (provided by the [`IntoIterator`] trait).
2590///
2591/// # Example
2592///
2593/// ```
2594/// use thin_vec::thin_vec;
2595///
2596/// let v = thin_vec![0, 1, 2];
2597/// let iter: thin_vec::IntoIter<_> = v.into_iter();
2598/// ```
2599pub struct IntoIter<T> {
2600    vec: ThinVec<T>,
2601    start: usize,
2602}
2603
2604impl<T> IntoIter<T> {
2605    /// Returns the remaining items of this iterator as a slice.
2606    ///
2607    /// # Examples
2608    ///
2609    /// ```
2610    /// use thin_vec::thin_vec;
2611    ///
2612    /// let vec = thin_vec!['a', 'b', 'c'];
2613    /// let mut into_iter = vec.into_iter();
2614    /// assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']);
2615    /// let _ = into_iter.next().unwrap();
2616    /// assert_eq!(into_iter.as_slice(), &['b', 'c']);
2617    /// ```
2618    pub fn as_slice(&self) -> &[T] {
2619        unsafe { slice::from_raw_parts(self.vec.data_raw().add(self.start), self.len()) }
2620    }
2621
2622    /// Returns the remaining items of this iterator as a mutable slice.
2623    ///
2624    /// # Examples
2625    ///
2626    /// ```
2627    /// use thin_vec::thin_vec;
2628    ///
2629    /// let vec = thin_vec!['a', 'b', 'c'];
2630    /// let mut into_iter = vec.into_iter();
2631    /// assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']);
2632    /// into_iter.as_mut_slice()[2] = 'z';
2633    /// assert_eq!(into_iter.next().unwrap(), 'a');
2634    /// assert_eq!(into_iter.next().unwrap(), 'b');
2635    /// assert_eq!(into_iter.next().unwrap(), 'z');
2636    /// ```
2637    pub fn as_mut_slice(&mut self) -> &mut [T] {
2638        unsafe { &mut *self.as_raw_mut_slice() }
2639    }
2640
2641    fn as_raw_mut_slice(&mut self) -> *mut [T] {
2642        unsafe { ptr::slice_from_raw_parts_mut(self.vec.data_raw().add(self.start), self.len()) }
2643    }
2644}
2645
2646impl<T> Iterator for IntoIter<T> {
2647    type Item = T;
2648    fn next(&mut self) -> Option<T> {
2649        if self.start == self.vec.len() {
2650            None
2651        } else {
2652            unsafe {
2653                let old_start = self.start;
2654                self.start += 1;
2655                Some(ptr::read(self.vec.data_raw().add(old_start)))
2656            }
2657        }
2658    }
2659
2660    fn size_hint(&self) -> (usize, Option<usize>) {
2661        let len = self.vec.len() - self.start;
2662        (len, Some(len))
2663    }
2664}
2665
2666impl<T> DoubleEndedIterator for IntoIter<T> {
2667    fn next_back(&mut self) -> Option<T> {
2668        if self.start == self.vec.len() {
2669            None
2670        } else {
2671            self.vec.pop()
2672        }
2673    }
2674}
2675
2676impl<T> ExactSizeIterator for IntoIter<T> {}
2677
2678impl<T> core::iter::FusedIterator for IntoIter<T> {}
2679
2680// SAFETY: the length calculation is trivial, we're an array! And if it's wrong we're So Screwed.
2681#[cfg(feature = "unstable")]
2682unsafe impl<T> core::iter::TrustedLen for IntoIter<T> {}
2683
2684impl<T> Drop for IntoIter<T> {
2685    #[inline]
2686    fn drop(&mut self) {
2687        #[cold]
2688        #[inline(never)]
2689        fn drop_non_singleton<T>(this: &mut IntoIter<T>) {
2690            // Leak on panic.
2691            struct DropGuard<'a, T>(&'a mut IntoIter<T>);
2692            impl<T> Drop for DropGuard<'_, T> {
2693                fn drop(&mut self) {
2694                    unsafe {
2695                        self.0.vec.set_len_non_singleton(0);
2696                    }
2697                }
2698            }
2699            unsafe {
2700                let guard = DropGuard(this);
2701                ptr::drop_in_place(&mut guard.0.vec[guard.0.start..]);
2702            }
2703        }
2704
2705        if !self.vec.is_singleton() {
2706            drop_non_singleton(self);
2707        }
2708    }
2709}
2710
2711impl<T: fmt::Debug> fmt::Debug for IntoIter<T> {
2712    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2713        f.debug_tuple("IntoIter").field(&self.as_slice()).finish()
2714    }
2715}
2716
2717impl<T> AsRef<[T]> for IntoIter<T> {
2718    fn as_ref(&self) -> &[T] {
2719        self.as_slice()
2720    }
2721}
2722
2723impl<T: Clone> Clone for IntoIter<T> {
2724    #[allow(clippy::into_iter_on_ref)]
2725    fn clone(&self) -> Self {
2726        // Just create a new `ThinVec` from the remaining elements and IntoIter it
2727        self.as_slice()
2728            .into_iter()
2729            .cloned()
2730            .collect::<ThinVec<_>>()
2731            .into_iter()
2732    }
2733}
2734
2735/// A draining iterator for `ThinVec<T>`.
2736///
2737/// This `struct` is created by [`ThinVec::drain`].
2738/// See its documentation for more.
2739///
2740/// # Example
2741///
2742/// ```
2743/// use thin_vec::thin_vec;
2744///
2745/// let mut v = thin_vec![0, 1, 2];
2746/// let iter: thin_vec::Drain<_> = v.drain(..);
2747/// ```
2748pub struct Drain<'a, T> {
2749    // Ok so ThinVec::drain takes a range of the ThinVec and yields the contents by-value,
2750    // then backshifts the array. During iteration the array is in an unsound state
2751    // (big deinitialized hole in it), and this is very dangerous.
2752    //
2753    // Our first line of defense is the borrow checker: we have a mutable borrow, so nothing
2754    // can access the ThinVec while we exist. As long as we make sure the ThinVec is in a valid
2755    // state again before we release the borrow, everything should be A-OK! We do this cleanup
2756    // in our Drop impl.
2757    //
2758    // Unfortunately, that's unsound, because mem::forget exists and The Leakpocalypse Is Real.
2759    // So we can't actually guarantee our destructor runs before our borrow expires. Thankfully
2760    // this isn't fatal: we can just set the ThinVec's len to 0 at the start, so if anyone
2761    // leaks the Drain, we just leak everything the ThinVec contained out of spite! If they
2762    // *don't* leak us then we can properly repair the len in our Drop impl. This is known
2763    // as "leak amplification", and is the same approach std uses.
2764    //
2765    // But we can do slightly better than setting the len to 0! The drain breaks us up into
2766    // these parts:
2767    //
2768    // ```text
2769    //
2770    // [A, B, C, D, E, F, G, H, _, _]
2771    //  ____  __________  ____  ____
2772    //   |         |        |     |
2773    // prefix    drain     tail  spare-cap
2774    // ```
2775    //
2776    // As the drain iterator is consumed from both ends (DoubleEnded!), we'll start to look
2777    // like this:
2778    //
2779    // ```text
2780    // [A, B, _, _, E, _, G, H, _, _]
2781    //  ____  __________  ____  ____
2782    //   |         |        |     |
2783    // prefix    drain     tail   spare-cap
2784    // ```
2785    //
2786    // Note that the prefix is always valid and untouched, as such we can set the len
2787    // to the prefix when doing leak-amplification. As a bonus, we can use this value
2788    // to remember where the drain range starts. At the end we'll look like this
2789    // (we exhaust ourselves in our Drop impl):
2790    //
2791    // ```text
2792    // [A, B, _, _, _, _, G, H, _, _]
2793    // _____  __________  _____ ____
2794    //   |         |        |     |
2795    //  len      drain     tail  spare-cap
2796    // ```
2797    //
2798    // And need to become this:
2799    //
2800    // ```text
2801    // [A, B, G, H, _, _, _, _, _, _]
2802    // ___________  ________________
2803    //     |               |
2804    //    len          spare-cap
2805    // ```
2806    //
2807    // All this requires is moving the tail back to the prefix (stored in `len`)
2808    // and setting `len` to `len + tail_len` to undo the leak amplification.
2809    /// An iterator over the elements we're removing.
2810    ///
2811    /// As we go we'll be `read`ing out of the shared refs yielded by this.
2812    /// It's ok to use Iter here because it promises to only take refs to the parts
2813    /// we haven't yielded yet.
2814    iter: Iter<'a, T>,
2815    /// The actual ThinVec, which we need to hold onto to undo the leak amplification
2816    /// and backshift the tail into place. This should only be accessed when we're
2817    /// completely done with the Iter in the `drop` impl of this type (or miri will get mad).
2818    ///
2819    /// Since we set the `len` of this to be before `Iter`, we can use that `len`
2820    /// to retrieve the index of the start of the drain range later.
2821    vec: NonNull<ThinVec<T>>,
2822    /// The one-past-the-end index of the drain range, or equivalently the start of the tail.
2823    end: usize,
2824    /// The length of the tail.
2825    tail: usize,
2826}
2827
2828impl<'a, T> Iterator for Drain<'a, T> {
2829    type Item = T;
2830    fn next(&mut self) -> Option<T> {
2831        self.iter.next().map(|x| unsafe { ptr::read(x) })
2832    }
2833
2834    fn size_hint(&self) -> (usize, Option<usize>) {
2835        self.iter.size_hint()
2836    }
2837}
2838
2839impl<'a, T> DoubleEndedIterator for Drain<'a, T> {
2840    fn next_back(&mut self) -> Option<T> {
2841        self.iter.next_back().map(|x| unsafe { ptr::read(x) })
2842    }
2843}
2844
2845impl<'a, T> ExactSizeIterator for Drain<'a, T> {}
2846
2847// SAFETY: we need to keep track of this perfectly Or Else anyway!
2848#[cfg(feature = "unstable")]
2849unsafe impl<T> core::iter::TrustedLen for Drain<'_, T> {}
2850
2851impl<T> core::iter::FusedIterator for Drain<'_, T> {}
2852
2853impl<'a, T> Drop for Drain<'a, T> {
2854    fn drop(&mut self) {
2855        // Consume the rest of the iterator.
2856        for _ in self.by_ref() {}
2857
2858        // Move the tail over the drained items, and update the length.
2859        unsafe {
2860            let vec = self.vec.as_mut();
2861
2862            // Don't mutate the empty singleton!
2863            if !vec.is_singleton() {
2864                let old_len = vec.len();
2865                let start = vec.data_raw().add(old_len);
2866                let end = vec.data_raw().add(self.end);
2867                ptr::copy(end, start, self.tail);
2868                vec.set_len_non_singleton(old_len + self.tail);
2869            }
2870        }
2871    }
2872}
2873
2874impl<T: fmt::Debug> fmt::Debug for Drain<'_, T> {
2875    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2876        f.debug_tuple("Drain").field(&self.iter.as_slice()).finish()
2877    }
2878}
2879
2880impl<'a, T> Drain<'a, T> {
2881    /// Returns the remaining items of this iterator as a slice.
2882    ///
2883    /// # Examples
2884    ///
2885    /// ```
2886    /// use thin_vec::thin_vec;
2887    ///
2888    /// let mut vec = thin_vec!['a', 'b', 'c'];
2889    /// let mut drain = vec.drain(..);
2890    /// assert_eq!(drain.as_slice(), &['a', 'b', 'c']);
2891    /// let _ = drain.next().unwrap();
2892    /// assert_eq!(drain.as_slice(), &['b', 'c']);
2893    /// ```
2894    #[must_use]
2895    pub fn as_slice(&self) -> &[T] {
2896        // SAFETY: this is A-OK because the elements that the underlying
2897        // iterator still points at are still logically initialized and contiguous.
2898        self.iter.as_slice()
2899    }
2900}
2901
2902impl<'a, T> AsRef<[T]> for Drain<'a, T> {
2903    fn as_ref(&self) -> &[T] {
2904        self.as_slice()
2905    }
2906}
2907
2908/// A splicing iterator for `ThinVec`.
2909///
2910/// This struct is created by [`ThinVec::splice`][].
2911/// See its documentation for more.
2912///
2913/// # Example
2914///
2915/// ```
2916/// use thin_vec::thin_vec;
2917///
2918/// let mut v = thin_vec![0, 1, 2];
2919/// let new = [7, 8];
2920/// let iter: thin_vec::Splice<_> = v.splice(1.., new);
2921/// ```
2922#[derive(Debug)]
2923pub struct Splice<'a, I: Iterator + 'a> {
2924    drain: Drain<'a, I::Item>,
2925    replace_with: I,
2926}
2927
2928impl<I: Iterator> Iterator for Splice<'_, I> {
2929    type Item = I::Item;
2930
2931    fn next(&mut self) -> Option<Self::Item> {
2932        self.drain.next()
2933    }
2934
2935    fn size_hint(&self) -> (usize, Option<usize>) {
2936        self.drain.size_hint()
2937    }
2938}
2939
2940impl<I: Iterator> DoubleEndedIterator for Splice<'_, I> {
2941    fn next_back(&mut self) -> Option<Self::Item> {
2942        self.drain.next_back()
2943    }
2944}
2945
2946impl<I: Iterator> ExactSizeIterator for Splice<'_, I> {}
2947
2948impl<I: Iterator> Drop for Splice<'_, I> {
2949    fn drop(&mut self) {
2950        // Ensure we've fully drained out the range
2951        self.drain.by_ref().for_each(drop);
2952
2953        unsafe {
2954            // If there's no tail elements, then the inner ThinVec is already
2955            // correct and we can just extend it like normal.
2956            if self.drain.tail == 0 {
2957                self.drain.vec.as_mut().extend(self.replace_with.by_ref());
2958                return;
2959            }
2960
2961            // First fill the range left by drain().
2962            if !self.drain.fill(&mut self.replace_with) {
2963                return;
2964            }
2965
2966            // There may be more elements. Use the lower bound as an estimate.
2967            let (lower_bound, _upper_bound) = self.replace_with.size_hint();
2968            if lower_bound > 0 {
2969                self.drain.move_tail(lower_bound);
2970                if !self.drain.fill(&mut self.replace_with) {
2971                    return;
2972                }
2973            }
2974
2975            // Collect any remaining elements.
2976            // This is a zero-length vector which does not allocate if `lower_bound` was exact.
2977            let mut collected = self
2978                .replace_with
2979                .by_ref()
2980                .collect::<Vec<I::Item>>()
2981                .into_iter();
2982            // Now we have an exact count.
2983            if collected.len() > 0 {
2984                self.drain.move_tail(collected.len());
2985                let filled = self.drain.fill(&mut collected);
2986                debug_assert!(filled);
2987                debug_assert_eq!(collected.len(), 0);
2988            }
2989        }
2990        // Let `Drain::drop` move the tail back if necessary and restore `vec.len`.
2991    }
2992}
2993
2994#[cfg(feature = "gecko-ffi")]
2995#[repr(C, align(8))]
2996struct AutoBuffer<T, const N: usize> {
2997    header: Header,
2998    buffer: mem::MaybeUninit<[T; N]>,
2999}
3000
3001#[doc(hidden)]
3002#[cfg(feature = "gecko-ffi")]
3003#[repr(C)]
3004pub struct AutoThinVec<T, const N: usize> {
3005    inner: ThinVec<T>,
3006    buffer: AutoBuffer<T, N>,
3007    _pinned: core::marker::PhantomPinned,
3008}
3009
3010#[cfg(feature = "gecko-ffi")]
3011impl<T, const N: usize> AutoThinVec<T, N> {
3012    /// Implementation detail for the auto_thin_vec macro.
3013    #[inline]
3014    #[doc(hidden)]
3015    pub fn new_unpinned() -> Self {
3016        // This condition is hard-coded in nsTArray.h
3017        assert!(
3018            core::mem::align_of::<T>() <= 8,
3019            "Can't handle alignments greater than 8"
3020        );
3021        assert_eq!(
3022            core::mem::offset_of!(Self, buffer),
3023            AUTO_ARRAY_HEADER_OFFSET
3024        );
3025        Self {
3026            inner: ThinVec::new(),
3027            buffer: AutoBuffer {
3028                header: Header {
3029                    _len: 0,
3030                    _cap: pack_capacity_and_auto(N as SizeType, true),
3031                },
3032                buffer: mem::MaybeUninit::uninit(),
3033            },
3034            _pinned: core::marker::PhantomPinned,
3035        }
3036    }
3037
3038    /// Returns a raw pointer to the inner ThinVec. Note that if you dereference it from rust, you
3039    /// need to make sure not to move the ThinVec manually via something like
3040    /// `std::mem::take(&mut auto_vec)`.
3041    pub fn as_mut_ptr(self: core::pin::Pin<&mut Self>) -> *mut ThinVec<T> {
3042        debug_assert!(self.is_auto_array());
3043        unsafe { &mut self.get_unchecked_mut().inner }
3044    }
3045
3046    #[inline]
3047    pub unsafe fn shrink_to_fit_known_singleton(self: core::pin::Pin<&mut Self>) {
3048        debug_assert!(self.is_singleton());
3049        let this = unsafe { self.get_unchecked_mut() };
3050        this.buffer.header.set_len(0);
3051        // TODO(emilio): Use NonNull::from_mut when msrv allows.
3052        this.inner.ptr = unsafe { NonNull::new_unchecked(&mut this.buffer.header) };
3053        debug_assert!(this.inner.is_auto_array());
3054        debug_assert!(this.inner.uses_stack_allocated_buffer());
3055    }
3056
3057    pub fn shrink_to_fit(self: core::pin::Pin<&mut Self>) {
3058        let this = unsafe { self.get_unchecked_mut() };
3059        this.inner.shrink_to_fit();
3060        debug_assert!(this.inner.is_auto_array());
3061    }
3062}
3063
3064// NOTE(emilio): DerefMut wouldn't be safe, see the comment in as_mut_ptr.
3065#[cfg(feature = "gecko-ffi")]
3066impl<T, const N: usize> Deref for AutoThinVec<T, N> {
3067    type Target = ThinVec<T>;
3068
3069    fn deref(&self) -> &Self::Target {
3070        &self.inner
3071    }
3072}
3073
3074/// Create a ThinVec<$ty> named `$name`, with capacity for `$cap` inline elements.
3075///
3076/// TODO(emilio): This would be a lot more convenient to use with super let, see
3077/// <https://github.com/rust-lang/rust/issues/139076>
3078#[cfg(feature = "gecko-ffi")]
3079#[macro_export]
3080macro_rules! auto_thin_vec {
3081    (let $name:ident : [$ty:ty; $cap:literal]) => {
3082        let auto_vec = $crate::AutoThinVec::<$ty, $cap>::new_unpinned();
3083        let mut $name = core::pin::pin!(auto_vec);
3084        unsafe { $name.as_mut().shrink_to_fit_known_singleton() };
3085    };
3086}
3087
3088/// Private helper methods for `Splice::drop`
3089impl<T> Drain<'_, T> {
3090    /// The range from `self.vec.len` to `self.tail_start` contains elements
3091    /// that have been moved out.
3092    /// Fill that range as much as possible with new elements from the `replace_with` iterator.
3093    /// Returns `true` if we filled the entire range. (`replace_with.next()` didn’t return `None`.)
3094    unsafe fn fill<I: Iterator<Item = T>>(&mut self, replace_with: &mut I) -> bool {
3095        let vec = unsafe { self.vec.as_mut() };
3096        let range_start = vec.len();
3097        let range_end = self.end;
3098        let range_slice = unsafe {
3099            slice::from_raw_parts_mut(vec.data_raw().add(range_start), range_end - range_start)
3100        };
3101
3102        for place in range_slice {
3103            let Some(new_item) = replace_with.next() else {
3104                return false;
3105            };
3106            unsafe {
3107                ptr::write(place, new_item);
3108                vec.set_len(vec.len() + 1);
3109            }
3110        }
3111        true
3112    }
3113
3114    /// Makes room for inserting more elements before the tail.
3115    unsafe fn move_tail(&mut self, additional: usize) {
3116        let vec = unsafe { self.vec.as_mut() };
3117        let len = self.end + self.tail;
3118        vec.reserve(len.checked_add(additional).unwrap_cap_overflow());
3119
3120        let new_tail_start = self.end + additional;
3121        unsafe {
3122            let src = vec.data_raw().add(self.end);
3123            let dst = vec.data_raw().add(new_tail_start);
3124            ptr::copy(src, dst, self.tail);
3125        }
3126        self.end = new_tail_start;
3127    }
3128}
3129
3130/// An iterator for [`ThinVec`] which uses a closure to determine if an element should be removed.
3131#[must_use = "iterators are lazy and do nothing unless consumed"]
3132pub struct ExtractIf<'a, T, F> {
3133    vec: &'a mut ThinVec<T>,
3134    /// The index of the item that will be inspected by the next call to `next`.
3135    idx: usize,
3136    /// Elements at and beyond this point will be retained. Must be equal or smaller than `old_len`.
3137    end: usize,
3138    /// The number of items that have been drained (removed) thus far.
3139    del: usize,
3140    /// The original length of `vec` prior to draining.
3141    old_len: usize,
3142    /// The filter test predicate.
3143    pred: F,
3144}
3145
3146impl<T, F> Iterator for ExtractIf<'_, T, F>
3147where
3148    F: FnMut(&mut T) -> bool,
3149{
3150    type Item = T;
3151
3152    fn next(&mut self) -> Option<T> {
3153        unsafe {
3154            let v = self.vec.data_raw();
3155            while self.idx < self.end {
3156                let i = self.idx;
3157                let drained = (self.pred)(&mut *v.add(i));
3158                // Update the index *after* the predicate is called. If the index
3159                // is updated prior and the predicate panics, the element at this
3160                // index would be leaked.
3161                self.idx += 1;
3162                if drained {
3163                    self.del += 1;
3164                    return Some(ptr::read(v.add(i)));
3165                } else if self.del > 0 {
3166                    let del = self.del;
3167                    let src: *const T = v.add(i);
3168                    let dst: *mut T = v.add(i - del);
3169                    ptr::copy_nonoverlapping(src, dst, 1);
3170                }
3171            }
3172            None
3173        }
3174    }
3175
3176    fn size_hint(&self) -> (usize, Option<usize>) {
3177        (0, Some(self.end - self.idx))
3178    }
3179}
3180
3181impl<A, F> Drop for ExtractIf<'_, A, F> {
3182    fn drop(&mut self) {
3183        unsafe {
3184            if self.idx < self.old_len && self.del > 0 {
3185                // This is a pretty messed up state, and there isn't really an
3186                // obviously right thing to do. We don't want to keep trying
3187                // to execute `pred`, so we just backshift all the unprocessed
3188                // elements and tell the vec that they still exist. The backshift
3189                // is required to prevent a double-drop of the last successfully
3190                // drained item prior to a panic in the predicate.
3191                let ptr = self.vec.data_raw();
3192                let src = ptr.add(self.idx);
3193                let dst = src.sub(self.del);
3194                let tail_len = self.old_len - self.idx;
3195                src.copy_to(dst, tail_len);
3196            }
3197
3198            self.vec.set_len(self.old_len - self.del);
3199        }
3200    }
3201}
3202
3203/// Write is implemented for `ThinVec<u8>` by appending to the vector.
3204/// The vector will grow as needed.
3205/// This implementation is identical to the one for `Vec<u8>`.
3206#[cfg(feature = "std")]
3207impl std::io::Write for ThinVec<u8> {
3208    #[inline]
3209    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
3210        self.extend_from_slice(buf);
3211        Ok(buf.len())
3212    }
3213
3214    #[inline]
3215    fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> {
3216        self.extend_from_slice(buf);
3217        Ok(())
3218    }
3219
3220    #[inline]
3221    fn flush(&mut self) -> std::io::Result<()> {
3222        Ok(())
3223    }
3224}
3225
3226// TODO: a million Index impls
3227
3228#[cfg(test)]
3229mod tests {
3230    use super::{MAX_CAP, ThinVec};
3231    use crate::alloc::{string::ToString, vec};
3232
3233    #[test]
3234    fn test_size_of() {
3235        use core::mem::size_of;
3236        assert_eq!(size_of::<ThinVec<u8>>(), size_of::<&u8>());
3237
3238        assert_eq!(size_of::<Option<ThinVec<u8>>>(), size_of::<&u8>());
3239    }
3240
3241    #[test]
3242    fn test_drop_empty() {
3243        ThinVec::<u8>::new();
3244    }
3245
3246    #[test]
3247    #[should_panic]
3248    fn test_cap_plus_header_rounded_up_overflows() {
3249        let _ = ThinVec::<u8>::with_capacity(isize::MAX as usize - size_of::<super::Header>());
3250    }
3251
3252    #[test]
3253    fn test_data_ptr_alignment() {
3254        let v = ThinVec::<u16>::new();
3255        assert!(v.data_raw() as usize % core::mem::align_of::<u16>() == 0);
3256
3257        let v = ThinVec::<u32>::new();
3258        assert!(v.data_raw() as usize % core::mem::align_of::<u32>() == 0);
3259
3260        let v = ThinVec::<u64>::new();
3261        assert!(v.data_raw() as usize % core::mem::align_of::<u64>() == 0);
3262    }
3263
3264    #[test]
3265    #[cfg_attr(
3266        feature = "gecko-ffi",
3267        should_panic = "nsTArray does not handle alignment above the header size correctly"
3268    )]
3269    fn test_overaligned_type_is_rejected_for_gecko_ffi_mode() {
3270        #[repr(align(16))]
3271        #[allow(unused)]
3272        struct Align16(u8);
3273
3274        let v = ThinVec::<Align16>::new();
3275        assert!(v.data_raw() as usize % 16 == 0);
3276    }
3277
3278    #[test]
3279    fn test_partial_eq() {
3280        assert_eq!(thin_vec![0], thin_vec![0]);
3281        assert_ne!(thin_vec![0], thin_vec![1]);
3282        assert_eq!(thin_vec![1, 2, 3], vec![1, 2, 3]);
3283    }
3284
3285    #[test]
3286    fn test_alloc() {
3287        let mut v = ThinVec::new();
3288        assert!(!v.has_allocation());
3289        v.push(1);
3290        assert!(v.has_allocation());
3291        v.pop();
3292        assert!(v.has_allocation());
3293        v.shrink_to_fit();
3294        assert!(!v.has_allocation());
3295        v.reserve(64);
3296        assert!(v.has_allocation());
3297        v = ThinVec::with_capacity(64);
3298        assert!(v.has_allocation());
3299        v = ThinVec::with_capacity(0);
3300        assert!(!v.has_allocation());
3301    }
3302
3303    #[test]
3304    fn test_drain_items() {
3305        let mut vec = thin_vec![1, 2, 3];
3306        let mut vec2 = thin_vec![];
3307        for i in vec.drain(..) {
3308            vec2.push(i);
3309        }
3310        assert_eq!(vec, []);
3311        assert_eq!(vec2, [1, 2, 3]);
3312    }
3313
3314    #[test]
3315    fn test_drain_items_reverse() {
3316        let mut vec = thin_vec![1, 2, 3];
3317        let mut vec2 = thin_vec![];
3318        for i in vec.drain(..).rev() {
3319            vec2.push(i);
3320        }
3321        assert_eq!(vec, []);
3322        assert_eq!(vec2, [3, 2, 1]);
3323    }
3324
3325    #[test]
3326    #[cfg_attr(
3327        feature = "gecko-ffi",
3328        should_panic = "ThinVec<T> cannot bridge to nsTArray<T> when T is zero-sized"
3329    )]
3330    fn test_drain_items_zero_sized() {
3331        let mut vec = thin_vec![(), (), ()];
3332        let mut vec2 = thin_vec![];
3333        for i in vec.drain(..) {
3334            vec2.push(i);
3335        }
3336        assert_eq!(vec, []);
3337        assert_eq!(vec2, [(), (), ()]);
3338    }
3339
3340    #[test]
3341    #[should_panic]
3342    fn test_drain_out_of_bounds() {
3343        let mut v = thin_vec![1, 2, 3, 4, 5];
3344        v.drain(5..6);
3345    }
3346
3347    #[test]
3348    fn test_drain_range() {
3349        let mut v = thin_vec![1, 2, 3, 4, 5];
3350        for _ in v.drain(4..) {}
3351        assert_eq!(v, &[1, 2, 3, 4]);
3352
3353        let mut v: ThinVec<_> = (1..6).map(|x| x.to_string()).collect();
3354        for _ in v.drain(1..4) {}
3355        assert_eq!(v, &[1.to_string(), 5.to_string()]);
3356
3357        let mut v: ThinVec<_> = (1..6).map(|x| x.to_string()).collect();
3358        for _ in v.drain(1..4).rev() {}
3359        assert_eq!(v, &[1.to_string(), 5.to_string()]);
3360    }
3361
3362    #[test]
3363    #[cfg_attr(
3364        feature = "gecko-ffi",
3365        should_panic = "ThinVec<T> cannot bridge to nsTArray<T> when T is zero-sized"
3366    )]
3367    fn test_drain_range_zst() {
3368        let mut v: ThinVec<_> = thin_vec![(); 5];
3369        for _ in v.drain(1..4).rev() {}
3370        assert_eq!(v, &[(), ()]);
3371    }
3372
3373    #[test]
3374    #[cfg_attr(
3375        feature = "gecko-ffi",
3376        should_panic = "ThinVec<T> cannot bridge to nsTArray<T> when T is zero-sized"
3377    )]
3378    fn test_drain_max_vec_size() {
3379        let mut v = ThinVec::<()>::with_capacity(MAX_CAP);
3380        unsafe {
3381            v.set_len(MAX_CAP);
3382        }
3383        for _ in v.drain(MAX_CAP - 1..) {}
3384        assert_eq!(v.len(), MAX_CAP - 1);
3385    }
3386
3387    #[test]
3388    fn test_clear() {
3389        let mut v = ThinVec::<i32>::new();
3390        assert_eq!(v.len(), 0);
3391        assert_eq!(v.capacity(), 0);
3392        assert_eq!(&v[..], &[]);
3393
3394        v.clear();
3395        assert_eq!(v.len(), 0);
3396        assert_eq!(v.capacity(), 0);
3397        assert_eq!(&v[..], &[]);
3398
3399        v.push(1);
3400        v.push(2);
3401        assert_eq!(v.len(), 2);
3402        assert!(v.capacity() >= 2);
3403        assert_eq!(&v[..], &[1, 2]);
3404
3405        v.clear();
3406        assert_eq!(v.len(), 0);
3407        assert!(v.capacity() >= 2);
3408        assert_eq!(&v[..], &[]);
3409
3410        v.push(3);
3411        v.push(4);
3412        assert_eq!(v.len(), 2);
3413        assert!(v.capacity() >= 2);
3414        assert_eq!(&v[..], &[3, 4]);
3415
3416        v.clear();
3417        assert_eq!(v.len(), 0);
3418        assert!(v.capacity() >= 2);
3419        assert_eq!(&v[..], &[]);
3420
3421        v.clear();
3422        assert_eq!(v.len(), 0);
3423        assert!(v.capacity() >= 2);
3424        assert_eq!(&v[..], &[]);
3425    }
3426
3427    #[test]
3428    fn test_empty_singleton_torture() {
3429        {
3430            let mut v = ThinVec::<i32>::new();
3431            assert_eq!(v.len(), 0);
3432            assert_eq!(v.capacity(), 0);
3433            assert!(v.is_empty());
3434            assert_eq!(&v[..], &[]);
3435            assert_eq!(&mut v[..], &mut []);
3436
3437            assert_eq!(v.pop(), None);
3438            assert_eq!(v.len(), 0);
3439            assert_eq!(v.capacity(), 0);
3440            assert_eq!(&v[..], &[]);
3441        }
3442
3443        {
3444            let v = ThinVec::<i32>::new();
3445            assert_eq!(v.into_iter().count(), 0);
3446
3447            let v = ThinVec::<i32>::new();
3448            #[allow(clippy::never_loop)]
3449            for _ in v.into_iter() {
3450                unreachable!();
3451            }
3452        }
3453
3454        {
3455            let mut v = ThinVec::<i32>::new();
3456            assert_eq!(v.drain(..).len(), 0);
3457
3458            #[allow(clippy::never_loop)]
3459            for _ in v.drain(..) {
3460                unreachable!()
3461            }
3462
3463            assert_eq!(v.len(), 0);
3464            assert_eq!(v.capacity(), 0);
3465            assert_eq!(&v[..], &[]);
3466        }
3467
3468        {
3469            let mut v = ThinVec::<i32>::new();
3470            assert_eq!(v.splice(.., []).len(), 0);
3471
3472            #[allow(clippy::never_loop)]
3473            for _ in v.splice(.., []) {
3474                unreachable!()
3475            }
3476
3477            assert_eq!(v.len(), 0);
3478            assert_eq!(v.capacity(), 0);
3479            assert_eq!(&v[..], &[]);
3480        }
3481
3482        {
3483            let mut v = ThinVec::<i32>::new();
3484            v.truncate(1);
3485            assert_eq!(v.len(), 0);
3486            assert_eq!(v.capacity(), 0);
3487            assert_eq!(&v[..], &[]);
3488
3489            v.truncate(0);
3490            assert_eq!(v.len(), 0);
3491            assert_eq!(v.capacity(), 0);
3492            assert_eq!(&v[..], &[]);
3493        }
3494
3495        {
3496            let mut v = ThinVec::<i32>::new();
3497            v.shrink_to_fit();
3498            assert_eq!(v.len(), 0);
3499            assert_eq!(v.capacity(), 0);
3500            assert_eq!(&v[..], &[]);
3501        }
3502
3503        {
3504            let mut v = ThinVec::<i32>::new();
3505            let new = v.split_off(0);
3506            assert_eq!(v.len(), 0);
3507            assert_eq!(v.capacity(), 0);
3508            assert_eq!(&v[..], &[]);
3509
3510            assert_eq!(new.len(), 0);
3511            assert_eq!(new.capacity(), 0);
3512            assert_eq!(&new[..], &[]);
3513        }
3514
3515        {
3516            let mut v = ThinVec::<i32>::new();
3517            let mut other = ThinVec::<i32>::new();
3518            v.append(&mut other);
3519
3520            assert_eq!(v.len(), 0);
3521            assert_eq!(v.capacity(), 0);
3522            assert_eq!(&v[..], &[]);
3523
3524            assert_eq!(other.len(), 0);
3525            assert_eq!(other.capacity(), 0);
3526            assert_eq!(&other[..], &[]);
3527        }
3528
3529        {
3530            let mut v = ThinVec::<i32>::new();
3531            v.reserve(0);
3532
3533            assert_eq!(v.len(), 0);
3534            assert_eq!(v.capacity(), 0);
3535            assert_eq!(&v[..], &[]);
3536        }
3537
3538        {
3539            let mut v = ThinVec::<i32>::new();
3540            v.reserve_exact(0);
3541
3542            assert_eq!(v.len(), 0);
3543            assert_eq!(v.capacity(), 0);
3544            assert_eq!(&v[..], &[]);
3545        }
3546
3547        {
3548            let mut v = ThinVec::<i32>::new();
3549            v.reserve(0);
3550
3551            assert_eq!(v.len(), 0);
3552            assert_eq!(v.capacity(), 0);
3553            assert_eq!(&v[..], &[]);
3554        }
3555
3556        {
3557            let v = ThinVec::<i32>::with_capacity(0);
3558
3559            assert_eq!(v.len(), 0);
3560            assert_eq!(v.capacity(), 0);
3561            assert_eq!(&v[..], &[]);
3562        }
3563
3564        {
3565            let v = ThinVec::<i32>::default();
3566
3567            assert_eq!(v.len(), 0);
3568            assert_eq!(v.capacity(), 0);
3569            assert_eq!(&v[..], &[]);
3570        }
3571
3572        {
3573            let mut v = ThinVec::<i32>::new();
3574            v.retain(|_| unreachable!());
3575
3576            assert_eq!(v.len(), 0);
3577            assert_eq!(v.capacity(), 0);
3578            assert_eq!(&v[..], &[]);
3579        }
3580
3581        {
3582            let mut v = ThinVec::<i32>::new();
3583            v.retain_mut(|_| unreachable!());
3584
3585            assert_eq!(v.len(), 0);
3586            assert_eq!(v.capacity(), 0);
3587            assert_eq!(&v[..], &[]);
3588        }
3589
3590        {
3591            let mut v = ThinVec::<i32>::new();
3592            v.dedup_by_key(|x| *x);
3593
3594            assert_eq!(v.len(), 0);
3595            assert_eq!(v.capacity(), 0);
3596            assert_eq!(&v[..], &[]);
3597        }
3598
3599        {
3600            let mut v = ThinVec::<i32>::new();
3601            v.dedup_by(|_, _| unreachable!());
3602
3603            assert_eq!(v.len(), 0);
3604            assert_eq!(v.capacity(), 0);
3605            assert_eq!(&v[..], &[]);
3606        }
3607
3608        {
3609            let v = ThinVec::<i32>::new();
3610            let v = v.clone();
3611
3612            assert_eq!(v.len(), 0);
3613            assert_eq!(v.capacity(), 0);
3614            assert_eq!(&v[..], &[]);
3615        }
3616    }
3617
3618    #[test]
3619    fn test_collect_capacity() {
3620        for i in 0..20 {
3621            let v = (0..i).into_iter().collect::<ThinVec<usize>>();
3622            assert_eq!(v.len(), i);
3623            assert_eq!(v.capacity(), i);
3624        }
3625    }
3626
3627    #[test]
3628    fn test_clone() {
3629        let mut v = ThinVec::<i32>::new();
3630        assert!(v.is_singleton());
3631        v.push(0);
3632        v.pop();
3633        assert!(!v.is_singleton());
3634
3635        let v2 = v.clone();
3636        assert!(v2.is_singleton());
3637    }
3638}
3639
3640#[cfg(test)]
3641mod std_tests {
3642    #![allow(clippy::reversed_empty_ranges)]
3643
3644    use super::*;
3645    use crate::alloc::{
3646        format,
3647        string::{String, ToString},
3648    };
3649    use core::mem::size_of;
3650
3651    struct DropCounter<'a> {
3652        count: &'a mut u32,
3653    }
3654
3655    impl<'a> Drop for DropCounter<'a> {
3656        fn drop(&mut self) {
3657            *self.count += 1;
3658        }
3659    }
3660
3661    #[test]
3662    fn test_small_vec_struct() {
3663        assert!(size_of::<ThinVec<u8>>() == size_of::<usize>());
3664    }
3665
3666    #[test]
3667    fn test_double_drop() {
3668        struct TwoVec<T> {
3669            x: ThinVec<T>,
3670            y: ThinVec<T>,
3671        }
3672
3673        let (mut count_x, mut count_y) = (0, 0);
3674        {
3675            let mut tv = TwoVec {
3676                x: ThinVec::new(),
3677                y: ThinVec::new(),
3678            };
3679            tv.x.push(DropCounter {
3680                count: &mut count_x,
3681            });
3682            tv.y.push(DropCounter {
3683                count: &mut count_y,
3684            });
3685
3686            // If ThinVec had a drop flag, here is where it would be zeroed.
3687            // Instead, it should rely on its internal state to prevent
3688            // doing anything significant when dropped multiple times.
3689            drop(tv.x);
3690
3691            // Here tv goes out of scope, tv.y should be dropped, but not tv.x.
3692        }
3693
3694        assert_eq!(count_x, 1);
3695        assert_eq!(count_y, 1);
3696    }
3697
3698    #[test]
3699    fn test_reserve() {
3700        let mut v = ThinVec::new();
3701        assert_eq!(v.capacity(), 0);
3702
3703        v.reserve(2);
3704        assert!(v.capacity() >= 2);
3705
3706        for i in 0..16 {
3707            v.push(i);
3708        }
3709
3710        assert!(v.capacity() >= 16);
3711        v.reserve(16);
3712        assert!(v.capacity() >= 32);
3713
3714        v.push(16);
3715
3716        v.reserve(16);
3717        assert!(v.capacity() >= 33)
3718    }
3719
3720    #[test]
3721    fn test_extend() {
3722        let mut v = ThinVec::<usize>::new();
3723        let mut w = ThinVec::new();
3724        v.extend(w.clone());
3725        assert_eq!(v, &[]);
3726
3727        v.extend(0..3);
3728        for i in 0..3 {
3729            w.push(i)
3730        }
3731
3732        assert_eq!(v, w);
3733
3734        v.extend(3..10);
3735        for i in 3..10 {
3736            w.push(i)
3737        }
3738
3739        assert_eq!(v, w);
3740
3741        v.extend(w.clone()); // specializes to `append`
3742        assert!(v.iter().eq(w.iter().chain(w.iter())));
3743
3744        // Double drop
3745        let mut count_x = 0;
3746        {
3747            let mut x = ThinVec::new();
3748            let y = thin_vec![DropCounter {
3749                count: &mut count_x
3750            }];
3751            x.extend(y);
3752        }
3753
3754        assert_eq!(count_x, 1);
3755    }
3756
3757    #[test]
3758    #[cfg_attr(
3759        feature = "gecko-ffi",
3760        should_panic = "ThinVec<T> cannot bridge to nsTArray<T> when T is zero-sized"
3761    )]
3762    fn test_extend_zst() {
3763        #[derive(PartialEq, Debug)]
3764        struct Foo;
3765
3766        let mut a = ThinVec::new();
3767        let b = thin_vec![Foo, Foo];
3768
3769        a.extend(b);
3770        assert_eq!(a, &[Foo, Foo]);
3771    }
3772
3773    /* TODO: implement extend for Iter<&Copy>
3774        #[test]
3775        fn test_extend_ref() {
3776            let mut v = thin_vec![1, 2];
3777            v.extend(&[3, 4, 5]);
3778
3779            assert_eq!(v.len(), 5);
3780            assert_eq!(v, [1, 2, 3, 4, 5]);
3781
3782            let w = thin_vec![6, 7];
3783            v.extend(&w);
3784
3785            assert_eq!(v.len(), 7);
3786            assert_eq!(v, [1, 2, 3, 4, 5, 6, 7]);
3787        }
3788    */
3789
3790    #[test]
3791    fn test_slice_from_mut() {
3792        let mut values = thin_vec![1, 2, 3, 4, 5];
3793        {
3794            let slice = &mut values[2..];
3795            assert!(slice == [3, 4, 5]);
3796            for p in slice {
3797                *p += 2;
3798            }
3799        }
3800
3801        assert!(values == [1, 2, 5, 6, 7]);
3802    }
3803
3804    #[test]
3805    fn test_slice_to_mut() {
3806        let mut values = thin_vec![1, 2, 3, 4, 5];
3807        {
3808            let slice = &mut values[..2];
3809            assert!(slice == [1, 2]);
3810            for p in slice {
3811                *p += 1;
3812            }
3813        }
3814
3815        assert!(values == [2, 3, 3, 4, 5]);
3816    }
3817
3818    #[test]
3819    fn test_split_at_mut() {
3820        let mut values = thin_vec![1, 2, 3, 4, 5];
3821        {
3822            let (left, right) = values.split_at_mut(2);
3823            {
3824                let left: &[_] = left;
3825                assert!(left[..left.len()] == [1, 2]);
3826            }
3827            for p in left {
3828                *p += 1;
3829            }
3830
3831            {
3832                let right: &[_] = right;
3833                assert!(right[..right.len()] == [3, 4, 5]);
3834            }
3835            for p in right {
3836                *p += 2;
3837            }
3838        }
3839
3840        assert_eq!(values, [2, 3, 5, 6, 7]);
3841    }
3842
3843    #[test]
3844    fn test_clone() {
3845        let v: ThinVec<i32> = thin_vec![];
3846        let w = thin_vec![1, 2, 3];
3847
3848        assert_eq!(v, v.clone());
3849
3850        let z = w.clone();
3851        assert_eq!(w, z);
3852        // they should be disjoint in memory.
3853        assert!(w.as_ptr() != z.as_ptr())
3854    }
3855
3856    #[test]
3857    fn test_clone_from() {
3858        let mut v = thin_vec![];
3859        let three: ThinVec<Box<_>> = thin_vec![Box::new(1), Box::new(2), Box::new(3)];
3860        let two: ThinVec<Box<_>> = thin_vec![Box::new(4), Box::new(5)];
3861        // zero, long
3862        v.clone_from(&three);
3863        assert_eq!(v, three);
3864
3865        // equal
3866        v.clone_from(&three);
3867        assert_eq!(v, three);
3868
3869        // long, short
3870        v.clone_from(&two);
3871        assert_eq!(v, two);
3872
3873        // short, long
3874        v.clone_from(&three);
3875        assert_eq!(v, three)
3876    }
3877
3878    #[test]
3879    fn test_retain() {
3880        let mut vec = thin_vec![1, 2, 3, 4];
3881        vec.retain(|&x| x % 2 == 0);
3882        assert_eq!(vec, [2, 4]);
3883    }
3884
3885    #[test]
3886    fn test_retain_mut() {
3887        let mut vec = thin_vec![9, 9, 9, 9];
3888        let mut i = 0;
3889        vec.retain_mut(|x| {
3890            i += 1;
3891            *x = i;
3892            i != 4
3893        });
3894        assert_eq!(vec, [1, 2, 3]);
3895    }
3896
3897    #[test]
3898    fn test_dedup() {
3899        fn case(a: ThinVec<i32>, b: ThinVec<i32>) {
3900            let mut v = a;
3901            v.dedup();
3902            assert_eq!(v, b);
3903        }
3904        case(thin_vec![], thin_vec![]);
3905        case(thin_vec![1], thin_vec![1]);
3906        case(thin_vec![1, 1], thin_vec![1]);
3907        case(thin_vec![1, 2, 3], thin_vec![1, 2, 3]);
3908        case(thin_vec![1, 1, 2, 3], thin_vec![1, 2, 3]);
3909        case(thin_vec![1, 2, 2, 3], thin_vec![1, 2, 3]);
3910        case(thin_vec![1, 2, 3, 3], thin_vec![1, 2, 3]);
3911        case(thin_vec![1, 1, 2, 2, 2, 3, 3], thin_vec![1, 2, 3]);
3912    }
3913
3914    #[test]
3915    fn test_dedup_by_key() {
3916        fn case(a: ThinVec<i32>, b: ThinVec<i32>) {
3917            let mut v = a;
3918            v.dedup_by_key(|i| *i / 10);
3919            assert_eq!(v, b);
3920        }
3921        case(thin_vec![], thin_vec![]);
3922        case(thin_vec![10], thin_vec![10]);
3923        case(thin_vec![10, 11], thin_vec![10]);
3924        case(thin_vec![10, 20, 30], thin_vec![10, 20, 30]);
3925        case(thin_vec![10, 11, 20, 30], thin_vec![10, 20, 30]);
3926        case(thin_vec![10, 20, 21, 30], thin_vec![10, 20, 30]);
3927        case(thin_vec![10, 20, 30, 31], thin_vec![10, 20, 30]);
3928        case(thin_vec![10, 11, 20, 21, 22, 30, 31], thin_vec![10, 20, 30]);
3929    }
3930
3931    #[test]
3932    fn test_dedup_by() {
3933        let mut vec = thin_vec!["foo", "bar", "Bar", "baz", "bar"];
3934        vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
3935
3936        assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
3937
3938        let mut vec = thin_vec![("foo", 1), ("foo", 2), ("bar", 3), ("bar", 4), ("bar", 5)];
3939        vec.dedup_by(|a, b| {
3940            a.0 == b.0 && {
3941                b.1 += a.1;
3942                true
3943            }
3944        });
3945
3946        assert_eq!(vec, [("foo", 3), ("bar", 12)]);
3947    }
3948
3949    #[test]
3950    fn test_dedup_unique() {
3951        let mut v0: ThinVec<Box<_>> = thin_vec![Box::new(1), Box::new(1), Box::new(2), Box::new(3)];
3952        v0.dedup();
3953        let mut v1: ThinVec<Box<_>> = thin_vec![Box::new(1), Box::new(2), Box::new(2), Box::new(3)];
3954        v1.dedup();
3955        let mut v2: ThinVec<Box<_>> = thin_vec![Box::new(1), Box::new(2), Box::new(3), Box::new(3)];
3956        v2.dedup();
3957        // If the boxed pointers were leaked or otherwise misused, valgrind
3958        // and/or rt should raise errors.
3959    }
3960
3961    #[test]
3962    #[cfg_attr(
3963        feature = "gecko-ffi",
3964        should_panic = "ThinVec<T> cannot bridge to nsTArray<T> when T is zero-sized"
3965    )]
3966    fn zero_sized_values() {
3967        let mut v = ThinVec::new();
3968        assert_eq!(v.len(), 0);
3969        v.push(());
3970        assert_eq!(v.len(), 1);
3971        v.push(());
3972        assert_eq!(v.len(), 2);
3973        assert_eq!(v.pop(), Some(()));
3974        assert_eq!(v.pop(), Some(()));
3975        assert_eq!(v.pop(), None);
3976
3977        assert_eq!(v.iter().count(), 0);
3978        v.push(());
3979        assert_eq!(v.iter().count(), 1);
3980        v.push(());
3981        assert_eq!(v.iter().count(), 2);
3982
3983        for &() in &v {}
3984
3985        assert_eq!(v.iter_mut().count(), 2);
3986        v.push(());
3987        assert_eq!(v.iter_mut().count(), 3);
3988        v.push(());
3989        assert_eq!(v.iter_mut().count(), 4);
3990
3991        for &mut () in &mut v {}
3992        unsafe {
3993            v.set_len(0);
3994        }
3995        assert_eq!(v.iter_mut().count(), 0);
3996    }
3997
3998    #[test]
3999    fn test_partition() {
4000        assert_eq!(
4001            thin_vec![].into_iter().partition(|x: &i32| *x < 3),
4002            (thin_vec![], thin_vec![])
4003        );
4004        assert_eq!(
4005            thin_vec![1, 2, 3].into_iter().partition(|x| *x < 4),
4006            (thin_vec![1, 2, 3], thin_vec![])
4007        );
4008        assert_eq!(
4009            thin_vec![1, 2, 3].into_iter().partition(|x| *x < 2),
4010            (thin_vec![1], thin_vec![2, 3])
4011        );
4012        assert_eq!(
4013            thin_vec![1, 2, 3].into_iter().partition(|x| *x < 0),
4014            (thin_vec![], thin_vec![1, 2, 3])
4015        );
4016    }
4017
4018    #[test]
4019    fn test_zip_unzip() {
4020        let z1 = thin_vec![(1, 4), (2, 5), (3, 6)];
4021
4022        let (left, right): (ThinVec<_>, ThinVec<_>) = z1.iter().cloned().unzip();
4023
4024        assert_eq!((1, 4), (left[0], right[0]));
4025        assert_eq!((2, 5), (left[1], right[1]));
4026        assert_eq!((3, 6), (left[2], right[2]));
4027    }
4028
4029    #[test]
4030    fn test_vec_truncate_drop() {
4031        static mut DROPS: u32 = 0;
4032        #[allow(unused)]
4033        struct Elem(i32);
4034        impl Drop for Elem {
4035            fn drop(&mut self) {
4036                unsafe {
4037                    DROPS += 1;
4038                }
4039            }
4040        }
4041
4042        let mut v = thin_vec![Elem(1), Elem(2), Elem(3), Elem(4), Elem(5)];
4043        assert_eq!(unsafe { DROPS }, 0);
4044        v.truncate(3);
4045        assert_eq!(unsafe { DROPS }, 2);
4046        v.truncate(0);
4047        assert_eq!(unsafe { DROPS }, 5);
4048    }
4049
4050    #[test]
4051    #[should_panic]
4052    fn test_vec_truncate_fail() {
4053        struct BadElem(i32);
4054        impl Drop for BadElem {
4055            fn drop(&mut self) {
4056                let BadElem(ref mut x) = *self;
4057                if *x == 0xbadbeef {
4058                    panic!("BadElem panic: 0xbadbeef")
4059                }
4060            }
4061        }
4062
4063        let mut v = thin_vec![BadElem(1), BadElem(2), BadElem(0xbadbeef), BadElem(4)];
4064        v.truncate(0);
4065    }
4066
4067    #[test]
4068    fn test_index() {
4069        let vec = thin_vec![1, 2, 3];
4070        assert!(vec[1] == 2);
4071    }
4072
4073    #[test]
4074    fn test_index_mut() {
4075        let mut vec = thin_vec![1, 2, 3];
4076        vec[1] = 22;
4077        assert!(vec[1] == 22);
4078    }
4079
4080    #[test]
4081    #[should_panic]
4082    fn test_index_out_of_bounds() {
4083        let vec = thin_vec![1, 2, 3];
4084        let _ = vec[3];
4085    }
4086
4087    #[test]
4088    #[should_panic]
4089    fn test_slice_out_of_bounds_1() {
4090        let x = thin_vec![1, 2, 3, 4, 5];
4091        let _ = &x[!0..];
4092    }
4093
4094    #[test]
4095    #[should_panic]
4096    fn test_slice_out_of_bounds_2() {
4097        let x = thin_vec![1, 2, 3, 4, 5];
4098        let _ = &x[..6];
4099    }
4100
4101    #[test]
4102    #[should_panic]
4103    fn test_slice_out_of_bounds_3() {
4104        let x = thin_vec![1, 2, 3, 4, 5];
4105        let _ = &x[!0..4];
4106    }
4107
4108    #[test]
4109    #[should_panic]
4110    fn test_slice_out_of_bounds_4() {
4111        let x = thin_vec![1, 2, 3, 4, 5];
4112        let _ = &x[1..6];
4113    }
4114
4115    #[test]
4116    #[should_panic]
4117    fn test_slice_out_of_bounds_5() {
4118        let x = thin_vec![1, 2, 3, 4, 5];
4119        let _ = &x[3..2];
4120    }
4121
4122    #[test]
4123    #[should_panic]
4124    fn test_swap_remove_empty() {
4125        let mut vec = ThinVec::<i32>::new();
4126        vec.swap_remove(0);
4127    }
4128
4129    #[test]
4130    fn test_move_items() {
4131        let vec = thin_vec![1, 2, 3];
4132        let mut vec2 = thin_vec![];
4133        for i in vec {
4134            vec2.push(i);
4135        }
4136        assert_eq!(vec2, [1, 2, 3]);
4137    }
4138
4139    #[test]
4140    fn test_move_items_reverse() {
4141        let vec = thin_vec![1, 2, 3];
4142        let mut vec2 = thin_vec![];
4143        for i in vec.into_iter().rev() {
4144            vec2.push(i);
4145        }
4146        assert_eq!(vec2, [3, 2, 1]);
4147    }
4148
4149    #[test]
4150    #[cfg_attr(
4151        feature = "gecko-ffi",
4152        should_panic = "ThinVec<T> cannot bridge to nsTArray<T> when T is zero-sized"
4153    )]
4154    fn test_move_items_zero_sized() {
4155        let vec = thin_vec![(), (), ()];
4156        let mut vec2 = thin_vec![];
4157        for i in vec {
4158            vec2.push(i);
4159        }
4160        assert_eq!(vec2, [(), (), ()]);
4161    }
4162
4163    #[test]
4164    fn test_drain_items() {
4165        let mut vec = thin_vec![1, 2, 3];
4166        let mut vec2 = thin_vec![];
4167        for i in vec.drain(..) {
4168            vec2.push(i);
4169        }
4170        assert_eq!(vec, []);
4171        assert_eq!(vec2, [1, 2, 3]);
4172    }
4173
4174    #[test]
4175    fn test_drain_items_reverse() {
4176        let mut vec = thin_vec![1, 2, 3];
4177        let mut vec2 = thin_vec![];
4178        for i in vec.drain(..).rev() {
4179            vec2.push(i);
4180        }
4181        assert_eq!(vec, []);
4182        assert_eq!(vec2, [3, 2, 1]);
4183    }
4184
4185    #[test]
4186    #[cfg_attr(
4187        feature = "gecko-ffi",
4188        should_panic = "ThinVec<T> cannot bridge to nsTArray<T> when T is zero-sized"
4189    )]
4190    fn test_drain_items_zero_sized() {
4191        let mut vec = thin_vec![(), (), ()];
4192        let mut vec2 = thin_vec![];
4193        for i in vec.drain(..) {
4194            vec2.push(i);
4195        }
4196        assert_eq!(vec, []);
4197        assert_eq!(vec2, [(), (), ()]);
4198    }
4199
4200    #[test]
4201    #[should_panic]
4202    fn test_drain_out_of_bounds() {
4203        let mut v = thin_vec![1, 2, 3, 4, 5];
4204        v.drain(5..6);
4205    }
4206
4207    #[test]
4208    fn test_drain_range() {
4209        let mut v = thin_vec![1, 2, 3, 4, 5];
4210        for _ in v.drain(4..) {}
4211        assert_eq!(v, &[1, 2, 3, 4]);
4212
4213        let mut v: ThinVec<_> = (1..6).map(|x| x.to_string()).collect();
4214        for _ in v.drain(1..4) {}
4215        assert_eq!(v, &[1.to_string(), 5.to_string()]);
4216
4217        let mut v: ThinVec<_> = (1..6).map(|x| x.to_string()).collect();
4218        for _ in v.drain(1..4).rev() {}
4219        assert_eq!(v, &[1.to_string(), 5.to_string()]);
4220    }
4221
4222    #[test]
4223    #[cfg_attr(
4224        feature = "gecko-ffi",
4225        should_panic = "ThinVec<T> cannot bridge to nsTArray<T> when T is zero-sized"
4226    )]
4227    fn test_drain_range_zst() {
4228        let mut v: ThinVec<_> = thin_vec![(); 5];
4229        for _ in v.drain(1..4).rev() {}
4230        assert_eq!(v, &[(), ()]);
4231    }
4232
4233    #[test]
4234    fn test_drain_inclusive_range() {
4235        let mut v = thin_vec!['a', 'b', 'c', 'd', 'e'];
4236        for _ in v.drain(1..=3) {}
4237        assert_eq!(v, &['a', 'e']);
4238
4239        let mut v: ThinVec<_> = (0..=5).map(|x| x.to_string()).collect();
4240        for _ in v.drain(1..=5) {}
4241        assert_eq!(v, &["0".to_string()]);
4242
4243        let mut v: ThinVec<String> = (0..=5).map(|x| x.to_string()).collect();
4244        for _ in v.drain(0..=5) {}
4245        assert_eq!(v, ThinVec::<String>::new());
4246
4247        let mut v: ThinVec<_> = (0..=5).map(|x| x.to_string()).collect();
4248        for _ in v.drain(0..=3) {}
4249        assert_eq!(v, &["4".to_string(), "5".to_string()]);
4250
4251        let mut v: ThinVec<_> = (0..=1).map(|x| x.to_string()).collect();
4252        for _ in v.drain(..=0) {}
4253        assert_eq!(v, &["1".to_string()]);
4254    }
4255
4256    #[test]
4257    #[cfg(not(feature = "gecko-ffi"))]
4258    fn test_drain_max_vec_size() {
4259        let mut v = ThinVec::<()>::with_capacity(MAX_CAP);
4260        unsafe {
4261            v.set_len(MAX_CAP);
4262        }
4263        for _ in v.drain(MAX_CAP - 1..) {}
4264        assert_eq!(v.len(), MAX_CAP - 1);
4265
4266        let mut v = ThinVec::<()>::with_capacity(MAX_CAP);
4267        unsafe {
4268            v.set_len(MAX_CAP);
4269        }
4270        for _ in v.drain(MAX_CAP - 1..=MAX_CAP - 1) {}
4271        assert_eq!(v.len(), MAX_CAP - 1);
4272    }
4273
4274    #[test]
4275    #[should_panic]
4276    fn test_drain_inclusive_out_of_bounds() {
4277        let mut v = thin_vec![1, 2, 3, 4, 5];
4278        v.drain(5..=5);
4279    }
4280
4281    #[test]
4282    fn test_splice() {
4283        let mut v = thin_vec![1, 2, 3, 4, 5];
4284        let a = [10, 11, 12];
4285        v.splice(2..4, a.iter().cloned());
4286        assert_eq!(v, &[1, 2, 10, 11, 12, 5]);
4287        v.splice(1..3, Some(20));
4288        assert_eq!(v, &[1, 20, 11, 12, 5]);
4289    }
4290
4291    #[test]
4292    fn test_splice_inclusive_range() {
4293        let mut v = thin_vec![1, 2, 3, 4, 5];
4294        let a = [10, 11, 12];
4295        let t1: ThinVec<_> = v.splice(2..=3, a.iter().cloned()).collect();
4296        assert_eq!(v, &[1, 2, 10, 11, 12, 5]);
4297        assert_eq!(t1, &[3, 4]);
4298        let t2: ThinVec<_> = v.splice(1..=2, Some(20)).collect();
4299        assert_eq!(v, &[1, 20, 11, 12, 5]);
4300        assert_eq!(t2, &[2, 10]);
4301    }
4302
4303    #[test]
4304    #[should_panic]
4305    fn test_splice_out_of_bounds() {
4306        let mut v = thin_vec![1, 2, 3, 4, 5];
4307        let a = [10, 11, 12];
4308        v.splice(5..6, a.iter().cloned());
4309    }
4310
4311    #[test]
4312    #[should_panic]
4313    fn test_splice_inclusive_out_of_bounds() {
4314        let mut v = thin_vec![1, 2, 3, 4, 5];
4315        let a = [10, 11, 12];
4316        v.splice(5..=5, a.iter().cloned());
4317    }
4318
4319    #[test]
4320    #[cfg_attr(
4321        feature = "gecko-ffi",
4322        should_panic = "ThinVec<T> cannot bridge to nsTArray<T> when T is zero-sized"
4323    )]
4324    fn test_splice_items_zero_sized() {
4325        let mut vec = thin_vec![(), (), ()];
4326        let vec2 = thin_vec![];
4327        let t: ThinVec<_> = vec.splice(1..2, vec2.iter().cloned()).collect();
4328        assert_eq!(vec, &[(), ()]);
4329        assert_eq!(t, &[()]);
4330    }
4331
4332    #[test]
4333    fn test_splice_unbounded() {
4334        let mut vec = thin_vec![1, 2, 3, 4, 5];
4335        let t: ThinVec<_> = vec.splice(.., None).collect();
4336        assert_eq!(vec, &[]);
4337        assert_eq!(t, &[1, 2, 3, 4, 5]);
4338    }
4339
4340    #[test]
4341    fn test_splice_forget() {
4342        let mut v = thin_vec![1, 2, 3, 4, 5];
4343        let a = [10, 11, 12];
4344        ::core::mem::forget(v.splice(2..4, a.iter().cloned()));
4345        assert_eq!(v, &[1, 2]);
4346    }
4347
4348    #[test]
4349    fn test_splice_from_empty() {
4350        let mut v = thin_vec![];
4351        let a = [10, 11, 12];
4352        v.splice(.., a.iter().cloned());
4353        assert_eq!(v, &[10, 11, 12]);
4354    }
4355
4356    /* probs won't ever impl this
4357        #[test]
4358        fn test_into_boxed_slice() {
4359            let xs = thin_vec![1, 2, 3];
4360            let ys = xs.into_boxed_slice();
4361            assert_eq!(&*ys, [1, 2, 3]);
4362        }
4363    */
4364
4365    #[test]
4366    fn test_append() {
4367        let mut vec = thin_vec![1, 2, 3];
4368        let mut vec2 = thin_vec![4, 5, 6];
4369        vec.append(&mut vec2);
4370        assert_eq!(vec, [1, 2, 3, 4, 5, 6]);
4371        assert_eq!(vec2, []);
4372    }
4373
4374    #[test]
4375    fn test_split_off() {
4376        let mut vec = thin_vec![1, 2, 3, 4, 5, 6];
4377        let vec2 = vec.split_off(4);
4378        assert_eq!(vec, [1, 2, 3, 4]);
4379        assert_eq!(vec2, [5, 6]);
4380    }
4381
4382    #[test]
4383    fn test_into_iter_as_slice() {
4384        let vec = thin_vec!['a', 'b', 'c'];
4385        let mut into_iter = vec.into_iter();
4386        assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']);
4387        let _ = into_iter.next().unwrap();
4388        assert_eq!(into_iter.as_slice(), &['b', 'c']);
4389        let _ = into_iter.next().unwrap();
4390        let _ = into_iter.next().unwrap();
4391        assert_eq!(into_iter.as_slice(), &[]);
4392    }
4393
4394    #[test]
4395    fn test_into_iter_as_mut_slice() {
4396        let vec = thin_vec!['a', 'b', 'c'];
4397        let mut into_iter = vec.into_iter();
4398        assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']);
4399        into_iter.as_mut_slice()[0] = 'x';
4400        into_iter.as_mut_slice()[1] = 'y';
4401        assert_eq!(into_iter.next().unwrap(), 'x');
4402        assert_eq!(into_iter.as_slice(), &['y', 'c']);
4403    }
4404
4405    #[test]
4406    fn test_into_iter_debug() {
4407        let vec = thin_vec!['a', 'b', 'c'];
4408        let into_iter = vec.into_iter();
4409        let debug = format!("{:?}", into_iter);
4410        assert_eq!(debug, "IntoIter(['a', 'b', 'c'])");
4411    }
4412
4413    #[test]
4414    fn test_into_iter_count() {
4415        assert_eq!(thin_vec![1, 2, 3].into_iter().count(), 3);
4416    }
4417
4418    #[test]
4419    fn test_into_iter_clone() {
4420        fn iter_equal<I: Iterator<Item = i32>>(it: I, slice: &[i32]) {
4421            let v: ThinVec<i32> = it.collect();
4422            assert_eq!(&v[..], slice);
4423        }
4424        let mut it = thin_vec![1, 2, 3].into_iter();
4425        iter_equal(it.clone(), &[1, 2, 3]);
4426        assert_eq!(it.next(), Some(1));
4427        let mut it = it.rev();
4428        iter_equal(it.clone(), &[3, 2]);
4429        assert_eq!(it.next(), Some(3));
4430        iter_equal(it.clone(), &[2]);
4431        assert_eq!(it.next(), Some(2));
4432        iter_equal(it.clone(), &[]);
4433        assert_eq!(it.next(), None);
4434    }
4435
4436    #[allow(dead_code)]
4437    fn assert_covariance() {
4438        fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> {
4439            d
4440        }
4441        fn into_iter<'new>(i: IntoIter<&'static str>) -> IntoIter<&'new str> {
4442            i
4443        }
4444    }
4445
4446    /* TODO: specialize vec.into_iter().collect::<ThinVec<_>>();
4447        #[test]
4448        fn from_into_inner() {
4449            let vec = thin_vec![1, 2, 3];
4450            let ptr = vec.as_ptr();
4451            let vec = vec.into_iter().collect::<ThinVec<_>>();
4452            assert_eq!(vec, [1, 2, 3]);
4453            assert_eq!(vec.as_ptr(), ptr);
4454
4455            let ptr = &vec[1] as *const _;
4456            let mut it = vec.into_iter();
4457            it.next().unwrap();
4458            let vec = it.collect::<ThinVec<_>>();
4459            assert_eq!(vec, [2, 3]);
4460            assert!(ptr != vec.as_ptr());
4461        }
4462    */
4463
4464    #[test]
4465    #[cfg_attr(feature = "gecko-ffi", ignore)]
4466    fn overaligned_allocations() {
4467        #[repr(align(256))]
4468        struct Foo(usize);
4469        let mut v = thin_vec![Foo(273)];
4470        for i in 0..0x1000 {
4471            v.reserve_exact(i);
4472            assert!(v[0].0 == 273);
4473            assert!(v.as_ptr() as usize & 0xff == 0);
4474            v.shrink_to_fit();
4475            assert!(v[0].0 == 273);
4476            assert!(v.as_ptr() as usize & 0xff == 0);
4477        }
4478    }
4479
4480    /* TODO: implement drain_filter?
4481        #[test]
4482        fn drain_filter_empty() {
4483            let mut vec: ThinVec<i32> = thin_vec![];
4484
4485            {
4486                let mut iter = vec.drain_filter(|_| true);
4487                assert_eq!(iter.size_hint(), (0, Some(0)));
4488                assert_eq!(iter.next(), None);
4489                assert_eq!(iter.size_hint(), (0, Some(0)));
4490                assert_eq!(iter.next(), None);
4491                assert_eq!(iter.size_hint(), (0, Some(0)));
4492            }
4493            assert_eq!(vec.len(), 0);
4494            assert_eq!(vec, thin_vec![]);
4495        }
4496
4497        #[test]
4498        fn drain_filter_zst() {
4499            let mut vec = thin_vec![(), (), (), (), ()];
4500            let initial_len = vec.len();
4501            let mut count = 0;
4502            {
4503                let mut iter = vec.drain_filter(|_| true);
4504                assert_eq!(iter.size_hint(), (0, Some(initial_len)));
4505                while let Some(_) = iter.next() {
4506                    count += 1;
4507                    assert_eq!(iter.size_hint(), (0, Some(initial_len - count)));
4508                }
4509                assert_eq!(iter.size_hint(), (0, Some(0)));
4510                assert_eq!(iter.next(), None);
4511                assert_eq!(iter.size_hint(), (0, Some(0)));
4512            }
4513
4514            assert_eq!(count, initial_len);
4515            assert_eq!(vec.len(), 0);
4516            assert_eq!(vec, thin_vec![]);
4517        }
4518
4519        #[test]
4520        fn drain_filter_false() {
4521            let mut vec = thin_vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
4522
4523            let initial_len = vec.len();
4524            let mut count = 0;
4525            {
4526                let mut iter = vec.drain_filter(|_| false);
4527                assert_eq!(iter.size_hint(), (0, Some(initial_len)));
4528                for _ in iter.by_ref() {
4529                    count += 1;
4530                }
4531                assert_eq!(iter.size_hint(), (0, Some(0)));
4532                assert_eq!(iter.next(), None);
4533                assert_eq!(iter.size_hint(), (0, Some(0)));
4534            }
4535
4536            assert_eq!(count, 0);
4537            assert_eq!(vec.len(), initial_len);
4538            assert_eq!(vec, thin_vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
4539        }
4540
4541        #[test]
4542        fn drain_filter_true() {
4543            let mut vec = thin_vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
4544
4545            let initial_len = vec.len();
4546            let mut count = 0;
4547            {
4548                let mut iter = vec.drain_filter(|_| true);
4549                assert_eq!(iter.size_hint(), (0, Some(initial_len)));
4550                while let Some(_) = iter.next() {
4551                    count += 1;
4552                    assert_eq!(iter.size_hint(), (0, Some(initial_len - count)));
4553                }
4554                assert_eq!(iter.size_hint(), (0, Some(0)));
4555                assert_eq!(iter.next(), None);
4556                assert_eq!(iter.size_hint(), (0, Some(0)));
4557            }
4558
4559            assert_eq!(count, initial_len);
4560            assert_eq!(vec.len(), 0);
4561            assert_eq!(vec, thin_vec![]);
4562        }
4563
4564        #[test]
4565        fn drain_filter_complex() {
4566
4567            {   //                [+xxx++++++xxxxx++++x+x++]
4568                let mut vec = thin_vec![1,
4569                                   2, 4, 6,
4570                                   7, 9, 11, 13, 15, 17,
4571                                   18, 20, 22, 24, 26,
4572                                   27, 29, 31, 33,
4573                                   34,
4574                                   35,
4575                                   36,
4576                                   37, 39];
4577
4578                let removed = vec.drain_filter(|x| *x % 2 == 0).collect::<ThinVec<_>>();
4579                assert_eq!(removed.len(), 10);
4580                assert_eq!(removed, thin_vec![2, 4, 6, 18, 20, 22, 24, 26, 34, 36]);
4581
4582                assert_eq!(vec.len(), 14);
4583                assert_eq!(vec, thin_vec![1, 7, 9, 11, 13, 15, 17, 27, 29, 31, 33, 35, 37, 39]);
4584            }
4585
4586            {   //                [xxx++++++xxxxx++++x+x++]
4587                let mut vec = thin_vec![2, 4, 6,
4588                                   7, 9, 11, 13, 15, 17,
4589                                   18, 20, 22, 24, 26,
4590                                   27, 29, 31, 33,
4591                                   34,
4592                                   35,
4593                                   36,
4594                                   37, 39];
4595
4596                let removed = vec.drain_filter(|x| *x % 2 == 0).collect::<ThinVec<_>>();
4597                assert_eq!(removed.len(), 10);
4598                assert_eq!(removed, thin_vec![2, 4, 6, 18, 20, 22, 24, 26, 34, 36]);
4599
4600                assert_eq!(vec.len(), 13);
4601                assert_eq!(vec, thin_vec![7, 9, 11, 13, 15, 17, 27, 29, 31, 33, 35, 37, 39]);
4602            }
4603
4604            {   //                [xxx++++++xxxxx++++x+x]
4605                let mut vec = thin_vec![2, 4, 6,
4606                                   7, 9, 11, 13, 15, 17,
4607                                   18, 20, 22, 24, 26,
4608                                   27, 29, 31, 33,
4609                                   34,
4610                                   35,
4611                                   36];
4612
4613                let removed = vec.drain_filter(|x| *x % 2 == 0).collect::<ThinVec<_>>();
4614                assert_eq!(removed.len(), 10);
4615                assert_eq!(removed, thin_vec![2, 4, 6, 18, 20, 22, 24, 26, 34, 36]);
4616
4617                assert_eq!(vec.len(), 11);
4618                assert_eq!(vec, thin_vec![7, 9, 11, 13, 15, 17, 27, 29, 31, 33, 35]);
4619            }
4620
4621            {   //                [xxxxxxxxxx+++++++++++]
4622                let mut vec = thin_vec![2, 4, 6, 8, 10, 12, 14, 16, 18, 20,
4623                                   1, 3, 5, 7, 9, 11, 13, 15, 17, 19];
4624
4625                let removed = vec.drain_filter(|x| *x % 2 == 0).collect::<ThinVec<_>>();
4626                assert_eq!(removed.len(), 10);
4627                assert_eq!(removed, thin_vec![2, 4, 6, 8, 10, 12, 14, 16, 18, 20]);
4628
4629                assert_eq!(vec.len(), 10);
4630                assert_eq!(vec, thin_vec![1, 3, 5, 7, 9, 11, 13, 15, 17, 19]);
4631            }
4632
4633            {   //                [+++++++++++xxxxxxxxxx]
4634                let mut vec = thin_vec![1, 3, 5, 7, 9, 11, 13, 15, 17, 19,
4635                                   2, 4, 6, 8, 10, 12, 14, 16, 18, 20];
4636
4637                let removed = vec.drain_filter(|x| *x % 2 == 0).collect::<ThinVec<_>>();
4638                assert_eq!(removed.len(), 10);
4639                assert_eq!(removed, thin_vec![2, 4, 6, 8, 10, 12, 14, 16, 18, 20]);
4640
4641                assert_eq!(vec.len(), 10);
4642                assert_eq!(vec, thin_vec![1, 3, 5, 7, 9, 11, 13, 15, 17, 19]);
4643            }
4644        }
4645    */
4646    #[test]
4647    fn test_reserve_exact() {
4648        // This is all the same as test_reserve
4649
4650        let mut v = ThinVec::new();
4651        assert_eq!(v.capacity(), 0);
4652
4653        v.reserve_exact(2);
4654        assert!(v.capacity() >= 2);
4655
4656        for i in 0..16 {
4657            v.push(i);
4658        }
4659
4660        assert!(v.capacity() >= 16);
4661        v.reserve_exact(16);
4662        assert!(v.capacity() >= 32);
4663
4664        v.push(16);
4665
4666        v.reserve_exact(16);
4667        assert!(v.capacity() >= 33)
4668    }
4669
4670    /* TODO: implement try_reserve
4671        #[test]
4672        fn test_try_reserve() {
4673
4674            // These are the interesting cases:
4675            // * exactly isize::MAX should never trigger a CapacityOverflow (can be OOM)
4676            // * > isize::MAX should always fail
4677            //    * On 16/32-bit should CapacityOverflow
4678            //    * On 64-bit should OOM
4679            // * overflow may trigger when adding `len` to `cap` (in number of elements)
4680            // * overflow may trigger when multiplying `new_cap` by size_of::<T> (to get bytes)
4681
4682            const MAX_CAP: usize = isize::MAX as usize;
4683            const MAX_USIZE: usize = usize::MAX;
4684
4685            // On 16/32-bit, we check that allocations don't exceed isize::MAX,
4686            // on 64-bit, we assume the OS will give an OOM for such a ridiculous size.
4687            // Any platform that succeeds for these requests is technically broken with
4688            // ptr::offset because LLVM is the worst.
4689            let guards_against_isize = size_of::<usize>() < 8;
4690
4691            {
4692                // Note: basic stuff is checked by test_reserve
4693                let mut empty_bytes: ThinVec<u8> = ThinVec::new();
4694
4695                // Check isize::MAX doesn't count as an overflow
4696                if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_CAP) {
4697                    panic!("isize::MAX shouldn't trigger an overflow!");
4698                }
4699                // Play it again, frank! (just to be sure)
4700                if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_CAP) {
4701                    panic!("isize::MAX shouldn't trigger an overflow!");
4702                }
4703
4704                if guards_against_isize {
4705                    // Check isize::MAX + 1 does count as overflow
4706                    if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_CAP + 1) {
4707                    } else { panic!("isize::MAX + 1 should trigger an overflow!") }
4708
4709                    // Check usize::MAX does count as overflow
4710                    if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_USIZE) {
4711                    } else { panic!("usize::MAX should trigger an overflow!") }
4712                } else {
4713                    // Check isize::MAX + 1 is an OOM
4714                    if let Err(AllocErr) = empty_bytes.try_reserve(MAX_CAP + 1) {
4715                    } else { panic!("isize::MAX + 1 should trigger an OOM!") }
4716
4717                    // Check usize::MAX is an OOM
4718                    if let Err(AllocErr) = empty_bytes.try_reserve(MAX_USIZE) {
4719                    } else { panic!("usize::MAX should trigger an OOM!") }
4720                }
4721            }
4722
4723
4724            {
4725                // Same basic idea, but with non-zero len
4726                let mut ten_bytes: ThinVec<u8> = thin_vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
4727
4728                if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10) {
4729                    panic!("isize::MAX shouldn't trigger an overflow!");
4730                }
4731                if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10) {
4732                    panic!("isize::MAX shouldn't trigger an overflow!");
4733                }
4734                if guards_against_isize {
4735                    if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 9) {
4736                    } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
4737                } else {
4738                    if let Err(AllocErr) = ten_bytes.try_reserve(MAX_CAP - 9) {
4739                    } else { panic!("isize::MAX + 1 should trigger an OOM!") }
4740                }
4741                // Should always overflow in the add-to-len
4742                if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_USIZE) {
4743                } else { panic!("usize::MAX should trigger an overflow!") }
4744            }
4745
4746
4747            {
4748                // Same basic idea, but with interesting type size
4749                let mut ten_u32s: ThinVec<u32> = thin_vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
4750
4751                if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP/4 - 10) {
4752                    panic!("isize::MAX shouldn't trigger an overflow!");
4753                }
4754                if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP/4 - 10) {
4755                    panic!("isize::MAX shouldn't trigger an overflow!");
4756                }
4757                if guards_against_isize {
4758                    if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP/4 - 9) {
4759                    } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
4760                } else {
4761                    if let Err(AllocErr) = ten_u32s.try_reserve(MAX_CAP/4 - 9) {
4762                    } else { panic!("isize::MAX + 1 should trigger an OOM!") }
4763                }
4764                // Should fail in the mul-by-size
4765                if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_USIZE - 20) {
4766                } else {
4767                    panic!("usize::MAX should trigger an overflow!");
4768                }
4769            }
4770
4771        }
4772
4773        #[test]
4774        fn test_try_reserve_exact() {
4775
4776            // This is exactly the same as test_try_reserve with the method changed.
4777            // See that test for comments.
4778
4779            const MAX_CAP: usize = isize::MAX as usize;
4780            const MAX_USIZE: usize = usize::MAX;
4781
4782            let guards_against_isize = size_of::<usize>() < 8;
4783
4784            {
4785                let mut empty_bytes: ThinVec<u8> = ThinVec::new();
4786
4787                if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_CAP) {
4788                    panic!("isize::MAX shouldn't trigger an overflow!");
4789                }
4790                if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_CAP) {
4791                    panic!("isize::MAX shouldn't trigger an overflow!");
4792                }
4793
4794                if guards_against_isize {
4795                    if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_CAP + 1) {
4796                    } else { panic!("isize::MAX + 1 should trigger an overflow!") }
4797
4798                    if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_USIZE) {
4799                    } else { panic!("usize::MAX should trigger an overflow!") }
4800                } else {
4801                    if let Err(AllocErr) = empty_bytes.try_reserve_exact(MAX_CAP + 1) {
4802                    } else { panic!("isize::MAX + 1 should trigger an OOM!") }
4803
4804                    if let Err(AllocErr) = empty_bytes.try_reserve_exact(MAX_USIZE) {
4805                    } else { panic!("usize::MAX should trigger an OOM!") }
4806                }
4807            }
4808
4809
4810            {
4811                let mut ten_bytes: ThinVec<u8> = thin_vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
4812
4813                if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) {
4814                    panic!("isize::MAX shouldn't trigger an overflow!");
4815                }
4816                if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) {
4817                    panic!("isize::MAX shouldn't trigger an overflow!");
4818                }
4819                if guards_against_isize {
4820                    if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
4821                    } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
4822                } else {
4823                    if let Err(AllocErr) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
4824                    } else { panic!("isize::MAX + 1 should trigger an OOM!") }
4825                }
4826                if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_USIZE) {
4827                } else { panic!("usize::MAX should trigger an overflow!") }
4828            }
4829
4830
4831            {
4832                let mut ten_u32s: ThinVec<u32> = thin_vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
4833
4834                if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 10) {
4835                    panic!("isize::MAX shouldn't trigger an overflow!");
4836                }
4837                if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 10) {
4838                    panic!("isize::MAX shouldn't trigger an overflow!");
4839                }
4840                if guards_against_isize {
4841                    if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 9) {
4842                    } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
4843                } else {
4844                    if let Err(AllocErr) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 9) {
4845                    } else { panic!("isize::MAX + 1 should trigger an OOM!") }
4846                }
4847                if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_USIZE - 20) {
4848                } else { panic!("usize::MAX should trigger an overflow!") }
4849            }
4850        }
4851    */
4852
4853    #[cfg(feature = "gecko-ffi")]
4854    #[test]
4855    fn auto_t_array_basic() {
4856        crate::auto_thin_vec!(let t: [u8; 10]);
4857        assert_eq!(t.capacity(), 10);
4858        assert!(t.is_auto_array());
4859        assert!(t.uses_stack_allocated_buffer());
4860        assert!(!t.has_allocation());
4861        assert_eq!(t.len(), 0);
4862        {
4863            let inner = unsafe { &mut *t.as_mut().as_mut_ptr() };
4864            for i in 0..30 {
4865                inner.push(i as u8);
4866            }
4867        }
4868
4869        assert!(t.is_auto_array());
4870        assert!(!t.uses_stack_allocated_buffer());
4871        assert_eq!(t.len(), 30);
4872        assert!(t.has_allocation());
4873        assert_eq!(t[5], 5);
4874        assert_eq!(t[29], 29);
4875        assert!(t.capacity() >= 30);
4876
4877        {
4878            let inner = unsafe { &mut *t.as_mut().as_mut_ptr() };
4879            inner.truncate(5);
4880        }
4881
4882        assert_eq!(t.len(), 5);
4883        assert!(t.capacity() >= 30);
4884        assert!(t.has_allocation());
4885        t.as_mut().shrink_to_fit();
4886        assert!(!t.has_allocation());
4887        assert!(t.is_auto_array());
4888        assert!(t.uses_stack_allocated_buffer());
4889        assert_eq!(t.capacity(), 10);
4890    }
4891
4892    #[test]
4893    #[cfg_attr(feature = "gecko-ffi", ignore)]
4894    fn test_header_data() {
4895        macro_rules! assert_aligned_head_ptr {
4896            ($typename:ty) => {{
4897                let v: ThinVec<$typename> = ThinVec::with_capacity(1 /* ensure allocation */);
4898                let head_ptr: *mut $typename = v.data_raw();
4899                assert_eq!(
4900                    head_ptr as usize % core::mem::align_of::<$typename>(),
4901                    0,
4902                    "expected Header::data<{}> to be aligned",
4903                    stringify!($typename)
4904                );
4905            }};
4906        }
4907
4908        const HEADER_SIZE: usize = core::mem::size_of::<Header>();
4909        assert_eq!(2 * core::mem::size_of::<usize>(), HEADER_SIZE);
4910
4911        #[repr(C, align(128))]
4912        struct Funky<T>(T);
4913        assert_eq!(padding::<Funky<()>>(), 128 - HEADER_SIZE);
4914        assert_aligned_head_ptr!(Funky<()>);
4915
4916        assert_eq!(padding::<Funky<u8>>(), 128 - HEADER_SIZE);
4917        assert_aligned_head_ptr!(Funky<u8>);
4918
4919        assert_eq!(padding::<Funky<[(); 1024]>>(), 128 - HEADER_SIZE);
4920        assert_aligned_head_ptr!(Funky<[(); 1024]>);
4921
4922        assert_eq!(padding::<Funky<[*mut usize; 1024]>>(), 128 - HEADER_SIZE);
4923        assert_aligned_head_ptr!(Funky<[*mut usize; 1024]>);
4924    }
4925
4926    #[cfg(feature = "serde")]
4927    use serde_test::{Token, assert_tokens};
4928
4929    #[test]
4930    #[cfg(feature = "serde")]
4931    fn test_ser_de_empty() {
4932        let vec = ThinVec::<u32>::new();
4933
4934        assert_tokens(&vec, &[Token::Seq { len: Some(0) }, Token::SeqEnd]);
4935    }
4936
4937    #[test]
4938    #[cfg(feature = "serde")]
4939    fn test_ser_de() {
4940        let mut vec = ThinVec::<u32>::new();
4941        vec.push(20);
4942        vec.push(55);
4943        vec.push(123);
4944
4945        assert_tokens(
4946            &vec,
4947            &[
4948                Token::Seq { len: Some(3) },
4949                Token::U32(20),
4950                Token::U32(55),
4951                Token::U32(123),
4952                Token::SeqEnd,
4953            ],
4954        );
4955    }
4956
4957    #[test]
4958    fn test_set_len() {
4959        let mut vec: ThinVec<u32> = thin_vec![];
4960        unsafe {
4961            vec.set_len(0); // at one point this caused a crash
4962        }
4963    }
4964
4965    #[test]
4966    #[should_panic(expected = "invalid set_len(1) on empty ThinVec")]
4967    fn test_set_len_invalid() {
4968        let mut vec: ThinVec<u32> = thin_vec![];
4969        unsafe {
4970            vec.set_len(1);
4971        }
4972    }
4973
4974    #[test]
4975    #[should_panic(expected = "capacity overflow")]
4976    fn test_capacity_overflow_header_too_big() {
4977        let vec: ThinVec<u8> = ThinVec::with_capacity(isize::MAX as usize - 2);
4978        assert!(vec.capacity() > 0);
4979    }
4980    #[test]
4981    #[should_panic(expected = "capacity overflow")]
4982    fn test_capacity_overflow_cap_too_big() {
4983        let vec: ThinVec<u8> = ThinVec::with_capacity(isize::MAX as usize + 1);
4984        assert!(vec.capacity() > 0);
4985    }
4986    #[test]
4987    #[should_panic(expected = "capacity overflow")]
4988    fn test_capacity_overflow_size_mul1() {
4989        let vec: ThinVec<u16> = ThinVec::with_capacity(isize::MAX as usize + 1);
4990        assert!(vec.capacity() > 0);
4991    }
4992    #[test]
4993    #[should_panic(expected = "capacity overflow")]
4994    fn test_capacity_overflow_size_mul2() {
4995        let vec: ThinVec<u16> = ThinVec::with_capacity(isize::MAX as usize / 2 + 1);
4996        assert!(vec.capacity() > 0);
4997    }
4998    #[test]
4999    #[should_panic(expected = "capacity overflow")]
5000    fn test_capacity_overflow_cap_really_isnt_isize() {
5001        let vec: ThinVec<u8> = ThinVec::with_capacity(isize::MAX as usize);
5002        assert!(vec.capacity() > 0);
5003    }
5004
5005    struct PanicBomb(&'static str);
5006
5007    impl Drop for PanicBomb {
5008        fn drop(&mut self) {
5009            if self.0 == "panic" {
5010                panic!("panic!");
5011            }
5012        }
5013    }
5014
5015    #[test]
5016    #[should_panic(expected = "panic!")]
5017    fn test_panic_into_iter() {
5018        let mut v = ThinVec::new();
5019        v.push(PanicBomb("normal1"));
5020        v.push(PanicBomb("panic"));
5021        v.push(PanicBomb("normal2"));
5022
5023        let mut iter = v.into_iter();
5024        iter.next();
5025    }
5026
5027    #[test]
5028    #[should_panic(expected = "panic!")]
5029    fn test_panic_clear() {
5030        let mut v = ThinVec::new();
5031        v.push(PanicBomb("normal1"));
5032        v.push(PanicBomb("panic"));
5033        v.push(PanicBomb("normal2"));
5034        v.clear();
5035    }
5036
5037    #[cfg(all(feature = "gecko-ffi", feature = "malloc_size_of"))]
5038    #[test]
5039    fn malloc_size_of_auto_array() {
5040        use malloc_size_of::{MallocShallowSizeOf, MallocSizeOfOps};
5041        use std::ffi::c_void;
5042
5043        extern "C" {
5044            fn malloc_usable_size(ptr: *const c_void) -> usize;
5045        }
5046
5047        unsafe extern "C" fn malloc_size_of(ptr: *const c_void) -> usize {
5048            unsafe { malloc_usable_size(ptr) }
5049        }
5050
5051        crate::auto_thin_vec!(let t: [u8; 4]);
5052        let mut ops = MallocSizeOfOps::new(malloc_size_of, None, None);
5053        let _ = MallocShallowSizeOf::shallow_size_of(&**t, &mut ops);
5054    }
5055}