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