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            ptr::drop_in_place(&mut self[..]);
1085            self.set_len(0); // could be the singleton
1086        }
1087    }
1088
1089    /// Extracts a slice containing the entire vector.
1090    ///
1091    /// Equivalent to `&s[..]`.
1092    ///
1093    /// # Examples
1094    ///
1095    /// ```
1096    /// use thin_vec::thin_vec;
1097    /// use std::io::{self, Write};
1098    /// let buffer = thin_vec![1, 2, 3, 5, 8];
1099    /// io::sink().write(buffer.as_slice()).unwrap();
1100    /// ```
1101    pub fn as_slice(&self) -> &[T] {
1102        unsafe { slice::from_raw_parts(self.data_raw(), self.len()) }
1103    }
1104
1105    /// Extracts a mutable slice of the entire vector.
1106    ///
1107    /// Equivalent to `&mut s[..]`.
1108    ///
1109    /// # Examples
1110    ///
1111    /// ```
1112    /// use thin_vec::thin_vec;
1113    /// use std::io::{self, Read};
1114    /// let mut buffer = vec![0; 3];
1115    /// io::repeat(0b101).read_exact(buffer.as_mut_slice()).unwrap();
1116    /// ```
1117    pub fn as_mut_slice(&mut self) -> &mut [T] {
1118        unsafe { slice::from_raw_parts_mut(self.data_raw(), self.len()) }
1119    }
1120
1121    /// Reserve capacity for at least `additional` more elements to be inserted.
1122    ///
1123    /// May reserve more space than requested, to avoid frequent reallocations.
1124    ///
1125    /// Panics if the new capacity overflows `usize`.
1126    ///
1127    /// Re-allocates only if `self.capacity() < self.len() + additional`.
1128    #[cfg(not(feature = "gecko-ffi"))]
1129    pub fn reserve(&mut self, additional: usize) {
1130        let len = self.len();
1131        let old_cap = self.capacity();
1132        let min_cap = len.checked_add(additional).unwrap_cap_overflow();
1133        if min_cap <= old_cap {
1134            return;
1135        }
1136        // Ensure the new capacity is at least double, to guarantee exponential growth.
1137        let double_cap = if old_cap == 0 {
1138            // skip to 4 because tiny ThinVecs are dumb; but not if that would cause overflow
1139            if mem::size_of::<T>() > (!0) / 8 {
1140                1
1141            } else {
1142                4
1143            }
1144        } else {
1145            old_cap.saturating_mul(2)
1146        };
1147        let new_cap = max(min_cap, double_cap);
1148        unsafe {
1149            self.reallocate(new_cap);
1150        }
1151    }
1152
1153    /// Reserve capacity for at least `additional` more elements to be inserted.
1154    ///
1155    /// This method mimics the growth algorithm used by the C++ implementation
1156    /// of nsTArray.
1157    #[cfg(feature = "gecko-ffi")]
1158    pub fn reserve(&mut self, additional: usize) {
1159        let elem_size = mem::size_of::<T>();
1160
1161        let len = self.len();
1162        let old_cap = self.capacity();
1163        let min_cap = len.checked_add(additional).unwrap_cap_overflow();
1164        if min_cap <= old_cap {
1165            return;
1166        }
1167
1168        // The growth logic can't handle zero-sized types, so we have to exit
1169        // early here.
1170        if elem_size == 0 {
1171            unsafe {
1172                self.reallocate(min_cap);
1173            }
1174            return;
1175        }
1176
1177        let min_cap_bytes = assert_size(min_cap)
1178            .checked_mul(assert_size(elem_size))
1179            .and_then(|x| x.checked_add(assert_size(mem::size_of::<Header>())))
1180            .unwrap();
1181
1182        // Perform some checked arithmetic to ensure all of the numbers we
1183        // compute will end up in range.
1184        let will_fit = min_cap_bytes.checked_mul(2).is_some();
1185        if !will_fit {
1186            panic!("Exceeded maximum nsTArray size");
1187        }
1188
1189        const SLOW_GROWTH_THRESHOLD: usize = 8 * 1024 * 1024;
1190
1191        let bytes = if min_cap > SLOW_GROWTH_THRESHOLD {
1192            // Grow by a minimum of 1.125x
1193            let old_cap_bytes = old_cap * elem_size + mem::size_of::<Header>();
1194            let min_growth = old_cap_bytes + (old_cap_bytes >> 3);
1195            let growth = max(min_growth, min_cap_bytes as usize);
1196
1197            // Round up to the next megabyte.
1198            const MB: usize = 1 << 20;
1199            MB * ((growth + MB - 1) / MB)
1200        } else {
1201            // Try to allocate backing buffers in powers of two.
1202            min_cap_bytes.next_power_of_two() as usize
1203        };
1204
1205        let cap = (bytes - core::mem::size_of::<Header>()) / elem_size;
1206        unsafe {
1207            self.reallocate(cap);
1208        }
1209    }
1210
1211    /// Reserves the minimum capacity for `additional` more elements to be inserted.
1212    ///
1213    /// Panics if the new capacity overflows `usize`.
1214    ///
1215    /// Re-allocates only if `self.capacity() < self.len() + additional`.
1216    pub fn reserve_exact(&mut self, additional: usize) {
1217        let new_cap = self.len().checked_add(additional).unwrap_cap_overflow();
1218        let old_cap = self.capacity();
1219        if new_cap > old_cap {
1220            unsafe {
1221                self.reallocate(new_cap);
1222            }
1223        }
1224    }
1225
1226    /// Shrinks the capacity of the vector as much as possible.
1227    ///
1228    /// It will drop down as close as possible to the length but the allocator
1229    /// may still inform the vector that there is space for a few more elements.
1230    ///
1231    /// # Examples
1232    ///
1233    /// ```
1234    /// use thin_vec::ThinVec;
1235    ///
1236    /// let mut vec = ThinVec::with_capacity(10);
1237    /// vec.extend([1, 2, 3]);
1238    /// assert_eq!(vec.capacity(), 10);
1239    /// vec.shrink_to_fit();
1240    /// assert!(vec.capacity() >= 3);
1241    /// ```
1242    pub fn shrink_to_fit(&mut self) {
1243        let old_cap = self.capacity();
1244        let new_cap = self.len();
1245        if new_cap >= old_cap {
1246            return;
1247        }
1248        #[cfg(feature = "gecko-ffi")]
1249        unsafe {
1250            let stack_buf = self.auto_array_header_mut();
1251            if !stack_buf.is_null() && (*stack_buf).cap() >= new_cap {
1252                // Try to switch to our auto-buffer.
1253                if stack_buf == self.ptr.as_ptr() {
1254                    return;
1255                }
1256                stack_buf
1257                    .add(1)
1258                    .cast::<T>()
1259                    .copy_from_nonoverlapping(self.data_raw(), new_cap);
1260                dealloc(self.ptr() as *mut u8, layout::<T>(old_cap));
1261                self.ptr = NonNull::new_unchecked(stack_buf);
1262                self.ptr.as_mut().set_len(new_cap);
1263                return;
1264            }
1265        }
1266        if new_cap == 0 {
1267            *self = ThinVec::new();
1268        } else {
1269            unsafe {
1270                self.reallocate(new_cap);
1271            }
1272        }
1273    }
1274
1275    /// Retains only the elements specified by the predicate.
1276    ///
1277    /// In other words, remove all elements `e` such that `f(&e)` returns `false`.
1278    /// This method operates in place and preserves the order of the retained
1279    /// elements.
1280    ///
1281    /// # Examples
1282    ///
1283    // A hack to avoid linking problems with `cargo test --features=gecko-ffi`.
1284    #[cfg_attr(not(feature = "gecko-ffi"), doc = "```")]
1285    #[cfg_attr(feature = "gecko-ffi", doc = "```ignore")]
1286    /// # #[macro_use] extern crate thin_vec;
1287    /// # fn main() {
1288    /// let mut vec = thin_vec![1, 2, 3, 4];
1289    /// vec.retain(|&x| x%2 == 0);
1290    /// assert_eq!(vec, [2, 4]);
1291    /// # }
1292    /// ```
1293    pub fn retain<F>(&mut self, mut f: F)
1294    where
1295        F: FnMut(&T) -> bool,
1296    {
1297        self.retain_mut(|x| f(&*x));
1298    }
1299
1300    /// Retains only the elements specified by the predicate, passing a mutable reference to it.
1301    ///
1302    /// In other words, remove all elements `e` such that `f(&mut e)` returns `false`.
1303    /// This method operates in place and preserves the order of the retained
1304    /// elements.
1305    ///
1306    /// # Examples
1307    ///
1308    // A hack to avoid linking problems with `cargo test --features=gecko-ffi`.
1309    #[cfg_attr(not(feature = "gecko-ffi"), doc = "```")]
1310    #[cfg_attr(feature = "gecko-ffi", doc = "```ignore")]
1311    /// # #[macro_use] extern crate thin_vec;
1312    /// # fn main() {
1313    /// let mut vec = thin_vec![1, 2, 3, 4, 5];
1314    /// vec.retain_mut(|x| {
1315    ///     *x += 1;
1316    ///     (*x)%2 == 0
1317    /// });
1318    /// assert_eq!(vec, [2, 4, 6]);
1319    /// # }
1320    /// ```
1321    pub fn retain_mut<F>(&mut self, mut f: F)
1322    where
1323        F: FnMut(&mut T) -> bool,
1324    {
1325        let len = self.len();
1326        let mut del = 0;
1327        {
1328            let v = &mut self[..];
1329
1330            for i in 0..len {
1331                if !f(&mut v[i]) {
1332                    del += 1;
1333                } else if del > 0 {
1334                    v.swap(i - del, i);
1335                }
1336            }
1337        }
1338        if del > 0 {
1339            self.truncate(len - del);
1340        }
1341    }
1342
1343    /// Removes consecutive elements in the vector that resolve to the same key.
1344    ///
1345    /// If the vector is sorted, this removes all duplicates.
1346    ///
1347    /// # Examples
1348    ///
1349    // A hack to avoid linking problems with `cargo test --features=gecko-ffi`.
1350    #[cfg_attr(not(feature = "gecko-ffi"), doc = "```")]
1351    #[cfg_attr(feature = "gecko-ffi", doc = "```ignore")]
1352    /// # #[macro_use] extern crate thin_vec;
1353    /// # fn main() {
1354    /// let mut vec = thin_vec![10, 20, 21, 30, 20];
1355    ///
1356    /// vec.dedup_by_key(|i| *i / 10);
1357    ///
1358    /// assert_eq!(vec, [10, 20, 30, 20]);
1359    /// # }
1360    /// ```
1361    pub fn dedup_by_key<F, K>(&mut self, mut key: F)
1362    where
1363        F: FnMut(&mut T) -> K,
1364        K: PartialEq<K>,
1365    {
1366        self.dedup_by(|a, b| key(a) == key(b))
1367    }
1368
1369    /// Removes consecutive elements in the vector according to a predicate.
1370    ///
1371    /// The `same_bucket` function is passed references to two elements from the vector, and
1372    /// returns `true` if the elements compare equal, or `false` if they do not. Only the first
1373    /// of adjacent equal items is kept.
1374    ///
1375    /// If the vector is sorted, this removes all duplicates.
1376    ///
1377    /// # Examples
1378    ///
1379    // A hack to avoid linking problems with `cargo test --features=gecko-ffi`.
1380    #[cfg_attr(not(feature = "gecko-ffi"), doc = "```")]
1381    #[cfg_attr(feature = "gecko-ffi", doc = "```ignore")]
1382    /// # #[macro_use] extern crate thin_vec;
1383    /// # fn main() {
1384    /// let mut vec = thin_vec!["foo", "bar", "Bar", "baz", "bar"];
1385    ///
1386    /// vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
1387    ///
1388    /// assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
1389    /// # }
1390    /// ```
1391    #[allow(clippy::swap_ptr_to_ref)]
1392    pub fn dedup_by<F>(&mut self, mut same_bucket: F)
1393    where
1394        F: FnMut(&mut T, &mut T) -> bool,
1395    {
1396        // See the comments in `Vec::dedup` for a detailed explanation of this code.
1397        unsafe {
1398            let ln = self.len();
1399            if ln <= 1 {
1400                return;
1401            }
1402
1403            // Avoid bounds checks by using raw pointers.
1404            let p = self.as_mut_ptr();
1405            let mut r: usize = 1;
1406            let mut w: usize = 1;
1407
1408            while r < ln {
1409                let p_r = p.add(r);
1410                let p_wm1 = p.add(w - 1);
1411                if !same_bucket(&mut *p_r, &mut *p_wm1) {
1412                    if r != w {
1413                        let p_w = p_wm1.add(1);
1414                        mem::swap(&mut *p_r, &mut *p_w);
1415                    }
1416                    w += 1;
1417                }
1418                r += 1;
1419            }
1420
1421            self.truncate(w);
1422        }
1423    }
1424
1425    /// Splits the collection into two at the given index.
1426    ///
1427    /// Returns a newly allocated vector containing the elements in the range
1428    /// `[at, len)`. After the call, the original vector will be left containing
1429    /// the elements `[0, at)` with its previous capacity unchanged.
1430    ///
1431    /// # Panics
1432    ///
1433    /// Panics if `at > len`.
1434    ///
1435    /// # Examples
1436    ///
1437    /// ```
1438    /// use thin_vec::thin_vec;
1439    ///
1440    /// let mut vec = thin_vec![1, 2, 3];
1441    /// let vec2 = vec.split_off(1);
1442    /// assert_eq!(vec, [1]);
1443    /// assert_eq!(vec2, [2, 3]);
1444    /// ```
1445    pub fn split_off(&mut self, at: usize) -> ThinVec<T> {
1446        let old_len = self.len();
1447        let new_vec_len = old_len - at;
1448
1449        assert!(at <= old_len, "Index out of bounds");
1450
1451        unsafe {
1452            let mut new_vec = ThinVec::with_capacity(new_vec_len);
1453
1454            ptr::copy_nonoverlapping(self.data_raw().add(at), new_vec.data_raw(), new_vec_len);
1455
1456            new_vec.set_len(new_vec_len); // could be the singleton
1457            self.set_len(at); // could be the singleton
1458
1459            new_vec
1460        }
1461    }
1462
1463    /// Moves all the elements of `other` into `self`, leaving `other` empty.
1464    ///
1465    /// # Panics
1466    ///
1467    /// Panics if the new capacity exceeds `isize::MAX` bytes.
1468    ///
1469    /// # Examples
1470    ///
1471    /// ```
1472    /// use thin_vec::thin_vec;
1473    ///
1474    /// let mut vec = thin_vec![1, 2, 3];
1475    /// let mut vec2 = thin_vec![4, 5, 6];
1476    /// vec.append(&mut vec2);
1477    /// assert_eq!(vec, [1, 2, 3, 4, 5, 6]);
1478    /// assert_eq!(vec2, []);
1479    /// ```
1480    pub fn append(&mut self, other: &mut ThinVec<T>) {
1481        self.extend(other.drain(..))
1482    }
1483
1484    /// Removes the specified range from the vector in bulk, returning all
1485    /// removed elements as an iterator. If the iterator is dropped before
1486    /// being fully consumed, it drops the remaining removed elements.
1487    ///
1488    /// The returned iterator keeps a mutable borrow on the vector to optimize
1489    /// its implementation.
1490    ///
1491    /// # Panics
1492    ///
1493    /// Panics if the starting point is greater than the end point or if
1494    /// the end point is greater than the length of the vector.
1495    ///
1496    /// # Leaking
1497    ///
1498    /// If the returned iterator goes out of scope without being dropped (due to
1499    /// [`mem::forget`], for example), the vector may have lost and leaked
1500    /// elements arbitrarily, including elements outside the range.
1501    ///
1502    /// # Examples
1503    ///
1504    /// ```
1505    /// use thin_vec::{ThinVec, thin_vec};
1506    ///
1507    /// let mut v = thin_vec![1, 2, 3];
1508    /// let u: ThinVec<_> = v.drain(1..).collect();
1509    /// assert_eq!(v, &[1]);
1510    /// assert_eq!(u, &[2, 3]);
1511    ///
1512    /// // A full range clears the vector, like `clear()` does
1513    /// v.drain(..);
1514    /// assert_eq!(v, &[]);
1515    /// ```
1516    pub fn drain<R>(&mut self, range: R) -> Drain<'_, T>
1517    where
1518        R: RangeBounds<usize>,
1519    {
1520        // See comments in the Drain struct itself for details on this
1521        let len = self.len();
1522        let start = match range.start_bound() {
1523            Bound::Included(&n) => n,
1524            Bound::Excluded(&n) => n + 1,
1525            Bound::Unbounded => 0,
1526        };
1527        let end = match range.end_bound() {
1528            Bound::Included(&n) => n + 1,
1529            Bound::Excluded(&n) => n,
1530            Bound::Unbounded => len,
1531        };
1532        assert!(start <= end);
1533        assert!(end <= len);
1534
1535        unsafe {
1536            // Set our length to the start bound
1537            self.set_len(start); // could be the singleton
1538
1539            let iter = slice::from_raw_parts(self.data_raw().add(start), end - start).iter();
1540
1541            Drain {
1542                iter,
1543                vec: NonNull::from(self),
1544                end,
1545                tail: len - end,
1546            }
1547        }
1548    }
1549
1550    /// Creates a splicing iterator that replaces the specified range in the vector
1551    /// with the given `replace_with` iterator and yields the removed items.
1552    /// `replace_with` does not need to be the same length as `range`.
1553    ///
1554    /// `range` is removed even if the iterator is not consumed until the end.
1555    ///
1556    /// It is unspecified how many elements are removed from the vector
1557    /// if the `Splice` value is leaked.
1558    ///
1559    /// The input iterator `replace_with` is only consumed when the `Splice` value is dropped.
1560    ///
1561    /// This is optimal if:
1562    ///
1563    /// * The tail (elements in the vector after `range`) is empty,
1564    /// * or `replace_with` yields fewer or equal elements than `range`’s length
1565    /// * or the lower bound of its `size_hint()` is exact.
1566    ///
1567    /// Otherwise, a temporary vector is allocated and the tail is moved twice.
1568    ///
1569    /// # Panics
1570    ///
1571    /// Panics if the starting point is greater than the end point or if
1572    /// the end point is greater than the length of the vector.
1573    ///
1574    /// # Examples
1575    ///
1576    /// ```
1577    /// use thin_vec::{ThinVec, thin_vec};
1578    ///
1579    /// let mut v = thin_vec![1, 2, 3, 4];
1580    /// let new = [7, 8, 9];
1581    /// let u: ThinVec<_> = v.splice(1..3, new).collect();
1582    /// assert_eq!(v, &[1, 7, 8, 9, 4]);
1583    /// assert_eq!(u, &[2, 3]);
1584    /// ```
1585    #[inline]
1586    pub fn splice<R, I>(&mut self, range: R, replace_with: I) -> Splice<'_, I::IntoIter>
1587    where
1588        R: RangeBounds<usize>,
1589        I: IntoIterator<Item = T>,
1590    {
1591        Splice {
1592            drain: self.drain(range),
1593            replace_with: replace_with.into_iter(),
1594        }
1595    }
1596
1597    /// Creates an iterator which uses a closure to determine if an element should be removed.
1598    ///
1599    /// If the closure returns true, then the element is removed and yielded.
1600    /// If the closure returns false, the element will remain in the vector and will not be yielded
1601    /// by the iterator.
1602    ///
1603    /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
1604    /// or the iteration short-circuits, then the remaining elements will be retained.
1605    /// Use [`ThinVec::retain`] with a negated predicate if you do not need the returned iterator.
1606    ///
1607    /// Using this method is equivalent to the following code:
1608    ///
1609    /// ```
1610    /// # use thin_vec::{ThinVec, thin_vec};
1611    /// # let some_predicate = |x: &mut i32| { *x == 2 || *x == 3 || *x == 6 };
1612    /// # let mut vec = thin_vec![1, 2, 3, 4, 5, 6];
1613    /// let mut i = 0;
1614    /// while i < vec.len() {
1615    ///     if some_predicate(&mut vec[i]) {
1616    ///         let val = vec.remove(i);
1617    ///         // your code here
1618    ///     } else {
1619    ///         i += 1;
1620    ///     }
1621    /// }
1622    ///
1623    /// # assert_eq!(vec, thin_vec![1, 4, 5]);
1624    /// ```
1625    ///
1626    /// But `extract_if` is easier to use. `extract_if` is also more efficient,
1627    /// because it can backshift the elements of the array in bulk.
1628    ///
1629    /// Note that `extract_if` also lets you mutate every element in the filter closure,
1630    /// regardless of whether you choose to keep or remove it.
1631    ///
1632    /// # Examples
1633    ///
1634    /// Splitting an array into evens and odds, reusing the original allocation:
1635    ///
1636    /// ```
1637    /// use thin_vec::{ThinVec, thin_vec};
1638    ///
1639    /// let mut numbers = thin_vec![1, 2, 3, 4, 5, 6, 8, 9, 11, 13, 14, 15];
1640    ///
1641    /// let evens = numbers.extract_if(.., |x| *x % 2 == 0).collect::<ThinVec<_>>();
1642    /// let odds = numbers;
1643    ///
1644    /// assert_eq!(evens, thin_vec![2, 4, 6, 8, 14]);
1645    /// assert_eq!(odds, thin_vec![1, 3, 5, 9, 11, 13, 15]);
1646    /// ```
1647    pub fn extract_if<F, R: RangeBounds<usize>>(
1648        &mut self,
1649        range: R,
1650        filter: F,
1651    ) -> ExtractIf<'_, T, F>
1652    where
1653        F: FnMut(&mut T) -> bool,
1654    {
1655        // Copy of https://github.com/rust-lang/rust/blob/ee361e8fca1c30e13e7a31cc82b64c045339d3a8/library/core/src/slice/index.rs#L37
1656        fn slice_index_fail(start: usize, end: usize, len: usize) -> ! {
1657            if start > len {
1658                panic!(
1659                    "range start index {} out of range for slice of length {}",
1660                    start, len
1661                )
1662            }
1663
1664            if end > len {
1665                panic!(
1666                    "range end index {} out of range for slice of length {}",
1667                    end, len
1668                )
1669            }
1670
1671            if start > end {
1672                panic!("slice index starts at {} but ends at {}", start, end)
1673            }
1674
1675            // Only reachable if the range was a `RangeInclusive` or a
1676            // `RangeToInclusive`, with `end == len`.
1677            panic!(
1678                "range end index {} out of range for slice of length {}",
1679                end, len
1680            )
1681        }
1682
1683        // Backport of https://github.com/rust-lang/rust/blob/ee361e8fca1c30e13e7a31cc82b64c045339d3a8/library/core/src/slice/index.rs#L855
1684        pub fn slice_range<R>(range: R, bounds: ops::RangeTo<usize>) -> ops::Range<usize>
1685        where
1686            R: ops::RangeBounds<usize>,
1687        {
1688            let len = bounds.end;
1689
1690            let end = match range.end_bound() {
1691                ops::Bound::Included(&end) if end >= len => slice_index_fail(0, end, len),
1692                // Cannot overflow because `end < len` implies `end < usize::MAX`.
1693                ops::Bound::Included(&end) => end + 1,
1694
1695                ops::Bound::Excluded(&end) if end > len => slice_index_fail(0, end, len),
1696                ops::Bound::Excluded(&end) => end,
1697                ops::Bound::Unbounded => len,
1698            };
1699
1700            let start = match range.start_bound() {
1701                ops::Bound::Excluded(&start) if start >= end => slice_index_fail(start, end, len),
1702                // Cannot overflow because `start < end` implies `start < usize::MAX`.
1703                ops::Bound::Excluded(&start) => start + 1,
1704
1705                ops::Bound::Included(&start) if start > end => slice_index_fail(start, end, len),
1706                ops::Bound::Included(&start) => start,
1707
1708                ops::Bound::Unbounded => 0,
1709            };
1710
1711            ops::Range { start, end }
1712        }
1713
1714        let old_len = self.len();
1715        let ops::Range { start, end } = slice_range(range, ..old_len);
1716
1717        // Guard against the vec getting leaked (leak amplification)
1718        unsafe {
1719            self.set_len(0);
1720        }
1721        ExtractIf {
1722            vec: self,
1723            idx: start,
1724            del: 0,
1725            end,
1726            old_len,
1727            pred: filter,
1728        }
1729    }
1730
1731    /// Resize the buffer and update its capacity, without changing the length.
1732    /// Unsafe because it can cause length to be greater than capacity.
1733    unsafe fn reallocate(&mut self, new_cap: usize) {
1734        debug_assert!(new_cap > 0);
1735        if self.has_allocation() {
1736            let old_cap = self.capacity();
1737            let ptr = realloc(
1738                self.ptr() as *mut u8,
1739                layout::<T>(old_cap),
1740                alloc_size::<T>(new_cap),
1741            ) as *mut Header;
1742
1743            if ptr.is_null() {
1744                handle_alloc_error(layout::<T>(new_cap))
1745            }
1746            (*ptr).set_cap_and_auto(new_cap, (*ptr).is_auto());
1747            self.ptr = NonNull::new_unchecked(ptr);
1748        } else {
1749            let new_header = header_with_capacity::<T>(new_cap, self.is_auto_array());
1750
1751            // If we get here and have a non-zero len, then we must be handling
1752            // a gecko auto array, and we have items in a stack buffer. We shouldn't
1753            // free it, but we should memcopy the contents out of it and mark it as empty.
1754            //
1755            // T is assumed to be trivially relocatable, as this is ~required
1756            // for Rust compatibility anyway. Furthermore, we assume C++ won't try
1757            // to unconditionally destroy the contents of the stack allocated buffer
1758            // (i.e. it's obfuscated behind a union).
1759            //
1760            // In effect, we are partially reimplementing the auto array move constructor
1761            // by leaving behind a valid empty instance.
1762            let len = self.len();
1763            if cfg!(feature = "gecko-ffi") && len > 0 {
1764                new_header
1765                    .as_ptr()
1766                    .add(1)
1767                    .cast::<T>()
1768                    .copy_from_nonoverlapping(self.data_raw(), len);
1769                self.set_len_non_singleton(0);
1770            }
1771
1772            self.ptr = new_header;
1773        }
1774    }
1775
1776    #[inline]
1777    #[allow(unused_unsafe)]
1778    fn is_singleton(&self) -> bool {
1779        unsafe { self.ptr.as_ptr() as *const Header == &EMPTY_HEADER }
1780    }
1781
1782    #[cfg(feature = "gecko-ffi")]
1783    #[inline]
1784    fn auto_array_header_mut(&mut self) -> *mut Header {
1785        if !self.is_auto_array() {
1786            return ptr::null_mut();
1787        }
1788        unsafe { (self as *mut Self).byte_add(AUTO_ARRAY_HEADER_OFFSET) as *mut Header }
1789    }
1790
1791    #[cfg(feature = "gecko-ffi")]
1792    #[inline]
1793    fn auto_array_header(&self) -> *const Header {
1794        if !self.is_auto_array() {
1795            return ptr::null_mut();
1796        }
1797        unsafe { (self as *const Self).byte_add(AUTO_ARRAY_HEADER_OFFSET) as *const Header }
1798    }
1799
1800    #[inline]
1801    fn is_auto_array(&self) -> bool {
1802        unsafe { self.ptr.as_ref().is_auto() }
1803    }
1804
1805    #[inline]
1806    fn uses_stack_allocated_buffer(&self) -> bool {
1807        #[cfg(feature = "gecko-ffi")]
1808        return self.auto_array_header() == self.ptr.as_ptr();
1809        #[cfg(not(feature = "gecko-ffi"))]
1810        return false;
1811    }
1812
1813    #[inline]
1814    fn has_allocation(&self) -> bool {
1815        !self.is_singleton() && !self.uses_stack_allocated_buffer()
1816    }
1817}
1818
1819impl<T: Clone> ThinVec<T> {
1820    /// Resizes the `Vec` in-place so that `len()` is equal to `new_len`.
1821    ///
1822    /// If `new_len` is greater than `len()`, the `Vec` is extended by the
1823    /// difference, with each additional slot filled with `value`.
1824    /// If `new_len` is less than `len()`, the `Vec` is simply truncated.
1825    ///
1826    /// # Examples
1827    ///
1828    // A hack to avoid linking problems with `cargo test --features=gecko-ffi`.
1829    #[cfg_attr(not(feature = "gecko-ffi"), doc = "```")]
1830    #[cfg_attr(feature = "gecko-ffi", doc = "```ignore")]
1831    /// # #[macro_use] extern crate thin_vec;
1832    /// # fn main() {
1833    /// let mut vec = thin_vec!["hello"];
1834    /// vec.resize(3, "world");
1835    /// assert_eq!(vec, ["hello", "world", "world"]);
1836    ///
1837    /// let mut vec = thin_vec![1, 2, 3, 4];
1838    /// vec.resize(2, 0);
1839    /// assert_eq!(vec, [1, 2]);
1840    /// # }
1841    /// ```
1842    pub fn resize(&mut self, new_len: usize, value: T) {
1843        let old_len = self.len();
1844
1845        if new_len > old_len {
1846            let additional = new_len - old_len;
1847            self.reserve(additional);
1848            for _ in 1..additional {
1849                self.push(value.clone());
1850            }
1851            // We can write the last element directly without cloning needlessly
1852            if additional > 0 {
1853                self.push(value);
1854            }
1855        } else if new_len < old_len {
1856            self.truncate(new_len);
1857        }
1858    }
1859
1860    /// Clones and appends all elements in a slice to the `ThinVec`.
1861    ///
1862    /// Iterates over the slice `other`, clones each element, and then appends
1863    /// it to this `ThinVec`. The `other` slice is traversed in-order.
1864    ///
1865    /// Note that this function is same as [`extend`] except that it is
1866    /// specialized to work with slices instead. If and when Rust gets
1867    /// specialization this function will likely be deprecated (but still
1868    /// available).
1869    ///
1870    /// # Examples
1871    ///
1872    /// ```
1873    /// use thin_vec::thin_vec;
1874    ///
1875    /// let mut vec = thin_vec![1];
1876    /// vec.extend_from_slice(&[2, 3, 4]);
1877    /// assert_eq!(vec, [1, 2, 3, 4]);
1878    /// ```
1879    ///
1880    /// [`extend`]: ThinVec::extend
1881    pub fn extend_from_slice(&mut self, other: &[T]) {
1882        self.extend(other.iter().cloned())
1883    }
1884}
1885
1886impl<T: PartialEq> ThinVec<T> {
1887    /// Removes consecutive repeated elements in the vector.
1888    ///
1889    /// If the vector is sorted, this removes all duplicates.
1890    ///
1891    /// # Examples
1892    ///
1893    // A hack to avoid linking problems with `cargo test --features=gecko-ffi`.
1894    #[cfg_attr(not(feature = "gecko-ffi"), doc = "```")]
1895    #[cfg_attr(feature = "gecko-ffi", doc = "```ignore")]
1896    /// # #[macro_use] extern crate thin_vec;
1897    /// # fn main() {
1898    /// let mut vec = thin_vec![1, 2, 2, 3, 2];
1899    ///
1900    /// vec.dedup();
1901    ///
1902    /// assert_eq!(vec, [1, 2, 3, 2]);
1903    /// # }
1904    /// ```
1905    pub fn dedup(&mut self) {
1906        self.dedup_by(|a, b| a == b)
1907    }
1908}
1909
1910impl<T> Drop for ThinVec<T> {
1911    #[inline]
1912    fn drop(&mut self) {
1913        #[cold]
1914        #[inline(never)]
1915        fn drop_non_singleton<T>(this: &mut ThinVec<T>) {
1916            unsafe {
1917                ptr::drop_in_place(&mut this[..]);
1918
1919                if this.uses_stack_allocated_buffer() {
1920                    return;
1921                }
1922
1923                dealloc(this.ptr() as *mut u8, layout::<T>(this.capacity()))
1924            }
1925        }
1926
1927        if !self.is_singleton() {
1928            drop_non_singleton(self);
1929        }
1930    }
1931}
1932
1933impl<T> Deref for ThinVec<T> {
1934    type Target = [T];
1935
1936    fn deref(&self) -> &[T] {
1937        self.as_slice()
1938    }
1939}
1940
1941impl<T> DerefMut for ThinVec<T> {
1942    fn deref_mut(&mut self) -> &mut [T] {
1943        self.as_mut_slice()
1944    }
1945}
1946
1947impl<T> Borrow<[T]> for ThinVec<T> {
1948    fn borrow(&self) -> &[T] {
1949        self.as_slice()
1950    }
1951}
1952
1953impl<T> BorrowMut<[T]> for ThinVec<T> {
1954    fn borrow_mut(&mut self) -> &mut [T] {
1955        self.as_mut_slice()
1956    }
1957}
1958
1959impl<T> AsRef<[T]> for ThinVec<T> {
1960    fn as_ref(&self) -> &[T] {
1961        self.as_slice()
1962    }
1963}
1964
1965impl<T> Extend<T> for ThinVec<T> {
1966    #[inline]
1967    fn extend<I>(&mut self, iter: I)
1968    where
1969        I: IntoIterator<Item = T>,
1970    {
1971        let mut iter = iter.into_iter();
1972        let hint = iter.size_hint().0;
1973        if hint > 0 {
1974            self.reserve(hint);
1975            for x in iter.by_ref().take(hint) {
1976                // SAFETY: `reserve(hint)` ensures the next `hint` calls of `push_unchecked`
1977                // have sufficient capacity.
1978                unsafe {
1979                    self.push_unchecked(x);
1980                }
1981            }
1982        }
1983
1984        // if the hint underestimated the iterator length,
1985        // push the remaining items with capacity check each time.
1986        for x in iter {
1987            self.push(x);
1988        }
1989    }
1990}
1991
1992impl<T: fmt::Debug> fmt::Debug for ThinVec<T> {
1993    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1994        fmt::Debug::fmt(&**self, f)
1995    }
1996}
1997
1998impl<T> Hash for ThinVec<T>
1999where
2000    T: Hash,
2001{
2002    fn hash<H>(&self, state: &mut H)
2003    where
2004        H: Hasher,
2005    {
2006        self[..].hash(state);
2007    }
2008}
2009
2010impl<T> PartialOrd for ThinVec<T>
2011where
2012    T: PartialOrd,
2013{
2014    #[inline]
2015    fn partial_cmp(&self, other: &ThinVec<T>) -> Option<Ordering> {
2016        self[..].partial_cmp(&other[..])
2017    }
2018}
2019
2020impl<T> Ord for ThinVec<T>
2021where
2022    T: Ord,
2023{
2024    #[inline]
2025    fn cmp(&self, other: &ThinVec<T>) -> Ordering {
2026        self[..].cmp(&other[..])
2027    }
2028}
2029
2030impl<A, B> PartialEq<ThinVec<B>> for ThinVec<A>
2031where
2032    A: PartialEq<B>,
2033{
2034    #[inline]
2035    fn eq(&self, other: &ThinVec<B>) -> bool {
2036        self[..] == other[..]
2037    }
2038}
2039
2040impl<A, B> PartialEq<Vec<B>> for ThinVec<A>
2041where
2042    A: PartialEq<B>,
2043{
2044    #[inline]
2045    fn eq(&self, other: &Vec<B>) -> bool {
2046        self[..] == other[..]
2047    }
2048}
2049
2050impl<A, B> PartialEq<[B]> for ThinVec<A>
2051where
2052    A: PartialEq<B>,
2053{
2054    #[inline]
2055    fn eq(&self, other: &[B]) -> bool {
2056        self[..] == other[..]
2057    }
2058}
2059
2060impl<'a, A, B> PartialEq<&'a [B]> for ThinVec<A>
2061where
2062    A: PartialEq<B>,
2063{
2064    #[inline]
2065    fn eq(&self, other: &&'a [B]) -> bool {
2066        self[..] == other[..]
2067    }
2068}
2069
2070// Serde impls based on
2071// https://github.com/bluss/arrayvec/blob/67ec907a98c0f40c4b76066fed3c1af59d35cf6a/src/arrayvec.rs#L1222-L1267
2072#[cfg(feature = "serde")]
2073impl<T: serde::Serialize> serde::Serialize for ThinVec<T> {
2074    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
2075    where
2076        S: serde::Serializer,
2077    {
2078        serializer.collect_seq(self.as_slice())
2079    }
2080}
2081
2082#[cfg(feature = "serde")]
2083impl<'de, T: serde::Deserialize<'de>> serde::Deserialize<'de> for ThinVec<T> {
2084    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
2085    where
2086        D: serde::Deserializer<'de>,
2087    {
2088        use serde::de::{SeqAccess, Visitor};
2089        use serde::Deserialize;
2090
2091        struct ThinVecVisitor<T>(PhantomData<T>);
2092
2093        impl<'de, T: Deserialize<'de>> Visitor<'de> for ThinVecVisitor<T> {
2094            type Value = ThinVec<T>;
2095
2096            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
2097                write!(formatter, "a sequence")
2098            }
2099
2100            fn visit_seq<SA>(self, mut seq: SA) -> Result<Self::Value, SA::Error>
2101            where
2102                SA: SeqAccess<'de>,
2103            {
2104                // Same policy as
2105                // https://github.com/serde-rs/serde/blob/ce0844b9ecc32377b5e4545d759d385a8c46bc6a/serde/src/private/size_hint.rs#L13
2106                let initial_capacity = seq.size_hint().unwrap_or_default().min(4096);
2107                let mut values = ThinVec::<T>::with_capacity(initial_capacity);
2108
2109                while let Some(value) = seq.next_element()? {
2110                    values.push(value);
2111                }
2112
2113                Ok(values)
2114            }
2115        }
2116
2117        deserializer.deserialize_seq(ThinVecVisitor::<T>(PhantomData))
2118    }
2119}
2120
2121#[cfg(feature = "malloc_size_of")]
2122impl<T> MallocShallowSizeOf for ThinVec<T> {
2123    fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
2124        if self.capacity() == 0 {
2125            // If it's the singleton we might not be a heap pointer.
2126            return 0;
2127        }
2128
2129        assert_eq!(
2130            std::mem::size_of::<Self>(),
2131            std::mem::size_of::<*const ()>()
2132        );
2133        unsafe { ops.malloc_size_of(*(self as *const Self as *const *const ())) }
2134    }
2135}
2136
2137#[cfg(feature = "malloc_size_of")]
2138impl<T: MallocSizeOf> MallocSizeOf for ThinVec<T> {
2139    fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
2140        let mut n = self.shallow_size_of(ops);
2141        for elem in self.iter() {
2142            n += elem.size_of(ops);
2143        }
2144        n
2145    }
2146}
2147
2148macro_rules! array_impls {
2149    ($($N:expr)*) => {$(
2150        impl<A, B> PartialEq<[B; $N]> for ThinVec<A> where A: PartialEq<B> {
2151            #[inline]
2152            fn eq(&self, other: &[B; $N]) -> bool { self[..] == other[..] }
2153        }
2154
2155        impl<'a, A, B> PartialEq<&'a [B; $N]> for ThinVec<A> where A: PartialEq<B> {
2156            #[inline]
2157            fn eq(&self, other: &&'a [B; $N]) -> bool { self[..] == other[..] }
2158        }
2159    )*}
2160}
2161
2162array_impls! {
2163    0  1  2  3  4  5  6  7  8  9
2164    10 11 12 13 14 15 16 17 18 19
2165    20 21 22 23 24 25 26 27 28 29
2166    30 31 32
2167}
2168
2169impl<T> Eq for ThinVec<T> where T: Eq {}
2170
2171impl<T> IntoIterator for ThinVec<T> {
2172    type Item = T;
2173    type IntoIter = IntoIter<T>;
2174
2175    fn into_iter(self) -> IntoIter<T> {
2176        IntoIter {
2177            vec: self,
2178            start: 0,
2179        }
2180    }
2181}
2182
2183impl<'a, T> IntoIterator for &'a ThinVec<T> {
2184    type Item = &'a T;
2185    type IntoIter = slice::Iter<'a, T>;
2186
2187    fn into_iter(self) -> slice::Iter<'a, T> {
2188        self.iter()
2189    }
2190}
2191
2192impl<'a, T> IntoIterator for &'a mut ThinVec<T> {
2193    type Item = &'a mut T;
2194    type IntoIter = slice::IterMut<'a, T>;
2195
2196    fn into_iter(self) -> slice::IterMut<'a, T> {
2197        self.iter_mut()
2198    }
2199}
2200
2201impl<T> Clone for ThinVec<T>
2202where
2203    T: Clone,
2204{
2205    #[inline]
2206    fn clone(&self) -> ThinVec<T> {
2207        #[cold]
2208        #[inline(never)]
2209        fn clone_non_singleton<T: Clone>(this: &ThinVec<T>) -> ThinVec<T> {
2210            let len = this.len();
2211            let mut new_vec = ThinVec::<T>::with_capacity(len);
2212            let mut data_raw = new_vec.data_raw();
2213            for x in this.iter() {
2214                unsafe {
2215                    ptr::write(data_raw, x.clone());
2216                    data_raw = data_raw.add(1);
2217                }
2218            }
2219            unsafe {
2220                // `this` is not the singleton, but `new_vec` will be if
2221                // `this` is empty.
2222                new_vec.set_len(len); // could be the singleton
2223            }
2224            new_vec
2225        }
2226
2227        if self.is_singleton() {
2228            ThinVec::new()
2229        } else {
2230            clone_non_singleton(self)
2231        }
2232    }
2233}
2234
2235impl<T> Default for ThinVec<T> {
2236    fn default() -> ThinVec<T> {
2237        ThinVec::new()
2238    }
2239}
2240
2241impl<T> FromIterator<T> for ThinVec<T> {
2242    #[inline]
2243    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> ThinVec<T> {
2244        let mut vec = ThinVec::new();
2245        vec.extend(iter);
2246        vec
2247    }
2248}
2249
2250impl<T: Clone> From<&[T]> for ThinVec<T> {
2251    /// Allocate a `ThinVec<T>` and fill it by cloning `s`'s items.
2252    ///
2253    /// # Examples
2254    ///
2255    /// ```
2256    /// use thin_vec::{ThinVec, thin_vec};
2257    ///
2258    /// assert_eq!(ThinVec::from(&[1, 2, 3][..]), thin_vec![1, 2, 3]);
2259    /// ```
2260    fn from(s: &[T]) -> ThinVec<T> {
2261        s.iter().cloned().collect()
2262    }
2263}
2264
2265impl<T: Clone> From<&mut [T]> for ThinVec<T> {
2266    /// Allocate a `ThinVec<T>` and fill it by cloning `s`'s items.
2267    ///
2268    /// # Examples
2269    ///
2270    /// ```
2271    /// use thin_vec::{ThinVec, thin_vec};
2272    ///
2273    /// assert_eq!(ThinVec::from(&mut [1, 2, 3][..]), thin_vec![1, 2, 3]);
2274    /// ```
2275    fn from(s: &mut [T]) -> ThinVec<T> {
2276        s.iter().cloned().collect()
2277    }
2278}
2279
2280impl<T, const N: usize> From<[T; N]> for ThinVec<T> {
2281    /// Allocate a `ThinVec<T>` and move `s`'s items into it.
2282    ///
2283    /// # Examples
2284    ///
2285    /// ```
2286    /// use thin_vec::{ThinVec, thin_vec};
2287    ///
2288    /// assert_eq!(ThinVec::from([1, 2, 3]), thin_vec![1, 2, 3]);
2289    /// ```
2290    fn from(s: [T; N]) -> ThinVec<T> {
2291        core::iter::IntoIterator::into_iter(s).collect()
2292    }
2293}
2294
2295impl<T> From<Box<[T]>> for ThinVec<T> {
2296    /// Convert a boxed slice into a vector by transferring ownership of
2297    /// the existing heap allocation.
2298    ///
2299    /// **NOTE:** unlike `std`, this must reallocate to change the layout!
2300    ///
2301    /// # Examples
2302    ///
2303    /// ```
2304    /// use thin_vec::{ThinVec, thin_vec};
2305    ///
2306    /// let b: Box<[i32]> = thin_vec![1, 2, 3].into_iter().collect();
2307    /// assert_eq!(ThinVec::from(b), thin_vec![1, 2, 3]);
2308    /// ```
2309    fn from(s: Box<[T]>) -> Self {
2310        // Can just lean on the fact that `Box<[T]>` -> `Vec<T>` is Free.
2311        Vec::from(s).into_iter().collect()
2312    }
2313}
2314
2315impl<T> From<Vec<T>> for ThinVec<T> {
2316    /// Convert a `std::Vec` into a `ThinVec`.
2317    ///
2318    /// **NOTE:** this must reallocate to change the layout!
2319    ///
2320    /// # Examples
2321    ///
2322    /// ```
2323    /// use thin_vec::{ThinVec, thin_vec};
2324    ///
2325    /// let b: Vec<i32> = vec![1, 2, 3];
2326    /// assert_eq!(ThinVec::from(b), thin_vec![1, 2, 3]);
2327    /// ```
2328    fn from(s: Vec<T>) -> Self {
2329        s.into_iter().collect()
2330    }
2331}
2332
2333impl<T> From<ThinVec<T>> for Vec<T> {
2334    /// Convert a `ThinVec` into a `std::Vec`.
2335    ///
2336    /// **NOTE:** this must reallocate to change the layout!
2337    ///
2338    /// # Examples
2339    ///
2340    /// ```
2341    /// use thin_vec::{ThinVec, thin_vec};
2342    ///
2343    /// let b: ThinVec<i32> = thin_vec![1, 2, 3];
2344    /// assert_eq!(Vec::from(b), vec![1, 2, 3]);
2345    /// ```
2346    fn from(s: ThinVec<T>) -> Self {
2347        s.into_iter().collect()
2348    }
2349}
2350
2351impl<T> From<ThinVec<T>> for Box<[T]> {
2352    /// Convert a vector into a boxed slice.
2353    ///
2354    /// If `v` has excess capacity, its items will be moved into a
2355    /// newly-allocated buffer with exactly the right capacity.
2356    ///
2357    /// **NOTE:** unlike `std`, this must reallocate to change the layout!
2358    ///
2359    /// # Examples
2360    ///
2361    /// ```
2362    /// use thin_vec::{ThinVec, thin_vec};
2363    /// assert_eq!(Box::from(thin_vec![1, 2, 3]), thin_vec![1, 2, 3].into_iter().collect());
2364    /// ```
2365    fn from(v: ThinVec<T>) -> Self {
2366        v.into_iter().collect()
2367    }
2368}
2369
2370impl From<&str> for ThinVec<u8> {
2371    /// Allocate a `ThinVec<u8>` and fill it with a UTF-8 string.
2372    ///
2373    /// # Examples
2374    ///
2375    /// ```
2376    /// use thin_vec::{ThinVec, thin_vec};
2377    ///
2378    /// assert_eq!(ThinVec::from("123"), thin_vec![b'1', b'2', b'3']);
2379    /// ```
2380    fn from(s: &str) -> ThinVec<u8> {
2381        From::from(s.as_bytes())
2382    }
2383}
2384
2385impl<T, const N: usize> TryFrom<ThinVec<T>> for [T; N] {
2386    type Error = ThinVec<T>;
2387
2388    /// Gets the entire contents of the `ThinVec<T>` as an array,
2389    /// if its size exactly matches that of the requested array.
2390    ///
2391    /// # Examples
2392    ///
2393    /// ```
2394    /// use thin_vec::{ThinVec, thin_vec};
2395    /// use std::convert::TryInto;
2396    ///
2397    /// assert_eq!(thin_vec![1, 2, 3].try_into(), Ok([1, 2, 3]));
2398    /// assert_eq!(<ThinVec<i32>>::new().try_into(), Ok([]));
2399    /// ```
2400    ///
2401    /// If the length doesn't match, the input comes back in `Err`:
2402    /// ```
2403    /// use thin_vec::{ThinVec, thin_vec};
2404    /// use std::convert::TryInto;
2405    ///
2406    /// let r: Result<[i32; 4], _> = (0..10).collect::<ThinVec<_>>().try_into();
2407    /// assert_eq!(r, Err(thin_vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]));
2408    /// ```
2409    ///
2410    /// If you're fine with just getting a prefix of the `ThinVec<T>`,
2411    /// you can call [`.truncate(N)`](ThinVec::truncate) first.
2412    /// ```
2413    /// use thin_vec::{ThinVec, thin_vec};
2414    /// use std::convert::TryInto;
2415    ///
2416    /// let mut v = ThinVec::from("hello world");
2417    /// v.sort();
2418    /// v.truncate(2);
2419    /// let [a, b]: [_; 2] = v.try_into().unwrap();
2420    /// assert_eq!(a, b' ');
2421    /// assert_eq!(b, b'd');
2422    /// ```
2423    fn try_from(mut vec: ThinVec<T>) -> Result<[T; N], ThinVec<T>> {
2424        if vec.len() != N {
2425            return Err(vec);
2426        }
2427
2428        // SAFETY: `.set_len(0)` is always sound.
2429        unsafe { vec.set_len(0) };
2430
2431        // SAFETY: A `ThinVec`'s pointer is always aligned properly, and
2432        // the alignment the array needs is the same as the items.
2433        // We checked earlier that we have sufficient items.
2434        // The items will not double-drop as the `set_len`
2435        // tells the `ThinVec` not to also drop them.
2436        let array = unsafe { ptr::read(vec.data_raw() as *const [T; N]) };
2437        Ok(array)
2438    }
2439}
2440
2441/// An iterator that moves out of a vector.
2442///
2443/// This `struct` is created by the [`ThinVec::into_iter`][]
2444/// (provided by the [`IntoIterator`] trait).
2445///
2446/// # Example
2447///
2448/// ```
2449/// use thin_vec::thin_vec;
2450///
2451/// let v = thin_vec![0, 1, 2];
2452/// let iter: thin_vec::IntoIter<_> = v.into_iter();
2453/// ```
2454pub struct IntoIter<T> {
2455    vec: ThinVec<T>,
2456    start: usize,
2457}
2458
2459impl<T> IntoIter<T> {
2460    /// Returns the remaining items of this iterator as a slice.
2461    ///
2462    /// # Examples
2463    ///
2464    /// ```
2465    /// use thin_vec::thin_vec;
2466    ///
2467    /// let vec = thin_vec!['a', 'b', 'c'];
2468    /// let mut into_iter = vec.into_iter();
2469    /// assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']);
2470    /// let _ = into_iter.next().unwrap();
2471    /// assert_eq!(into_iter.as_slice(), &['b', 'c']);
2472    /// ```
2473    pub fn as_slice(&self) -> &[T] {
2474        unsafe { slice::from_raw_parts(self.vec.data_raw().add(self.start), self.len()) }
2475    }
2476
2477    /// Returns the remaining items of this iterator as a mutable slice.
2478    ///
2479    /// # Examples
2480    ///
2481    /// ```
2482    /// use thin_vec::thin_vec;
2483    ///
2484    /// let vec = thin_vec!['a', 'b', 'c'];
2485    /// let mut into_iter = vec.into_iter();
2486    /// assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']);
2487    /// into_iter.as_mut_slice()[2] = 'z';
2488    /// assert_eq!(into_iter.next().unwrap(), 'a');
2489    /// assert_eq!(into_iter.next().unwrap(), 'b');
2490    /// assert_eq!(into_iter.next().unwrap(), 'z');
2491    /// ```
2492    pub fn as_mut_slice(&mut self) -> &mut [T] {
2493        unsafe { &mut *self.as_raw_mut_slice() }
2494    }
2495
2496    fn as_raw_mut_slice(&mut self) -> *mut [T] {
2497        unsafe { ptr::slice_from_raw_parts_mut(self.vec.data_raw().add(self.start), self.len()) }
2498    }
2499}
2500
2501impl<T> Iterator for IntoIter<T> {
2502    type Item = T;
2503    fn next(&mut self) -> Option<T> {
2504        if self.start == self.vec.len() {
2505            None
2506        } else {
2507            unsafe {
2508                let old_start = self.start;
2509                self.start += 1;
2510                Some(ptr::read(self.vec.data_raw().add(old_start)))
2511            }
2512        }
2513    }
2514
2515    fn size_hint(&self) -> (usize, Option<usize>) {
2516        let len = self.vec.len() - self.start;
2517        (len, Some(len))
2518    }
2519}
2520
2521impl<T> DoubleEndedIterator for IntoIter<T> {
2522    fn next_back(&mut self) -> Option<T> {
2523        if self.start == self.vec.len() {
2524            None
2525        } else {
2526            self.vec.pop()
2527        }
2528    }
2529}
2530
2531impl<T> ExactSizeIterator for IntoIter<T> {}
2532
2533impl<T> core::iter::FusedIterator for IntoIter<T> {}
2534
2535// SAFETY: the length calculation is trivial, we're an array! And if it's wrong we're So Screwed.
2536#[cfg(feature = "unstable")]
2537unsafe impl<T> core::iter::TrustedLen for IntoIter<T> {}
2538
2539impl<T> Drop for IntoIter<T> {
2540    #[inline]
2541    fn drop(&mut self) {
2542        #[cold]
2543        #[inline(never)]
2544        fn drop_non_singleton<T>(this: &mut IntoIter<T>) {
2545            unsafe {
2546                let mut vec = mem::replace(&mut this.vec, ThinVec::new());
2547                ptr::drop_in_place(&mut vec[this.start..]);
2548                vec.set_len_non_singleton(0)
2549            }
2550        }
2551
2552        if !self.vec.is_singleton() {
2553            drop_non_singleton(self);
2554        }
2555    }
2556}
2557
2558impl<T: fmt::Debug> fmt::Debug for IntoIter<T> {
2559    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2560        f.debug_tuple("IntoIter").field(&self.as_slice()).finish()
2561    }
2562}
2563
2564impl<T> AsRef<[T]> for IntoIter<T> {
2565    fn as_ref(&self) -> &[T] {
2566        self.as_slice()
2567    }
2568}
2569
2570impl<T: Clone> Clone for IntoIter<T> {
2571    #[allow(clippy::into_iter_on_ref)]
2572    fn clone(&self) -> Self {
2573        // Just create a new `ThinVec` from the remaining elements and IntoIter it
2574        self.as_slice()
2575            .into_iter()
2576            .cloned()
2577            .collect::<ThinVec<_>>()
2578            .into_iter()
2579    }
2580}
2581
2582/// A draining iterator for `ThinVec<T>`.
2583///
2584/// This `struct` is created by [`ThinVec::drain`].
2585/// See its documentation for more.
2586///
2587/// # Example
2588///
2589/// ```
2590/// use thin_vec::thin_vec;
2591///
2592/// let mut v = thin_vec![0, 1, 2];
2593/// let iter: thin_vec::Drain<_> = v.drain(..);
2594/// ```
2595pub struct Drain<'a, T> {
2596    // Ok so ThinVec::drain takes a range of the ThinVec and yields the contents by-value,
2597    // then backshifts the array. During iteration the array is in an unsound state
2598    // (big deinitialized hole in it), and this is very dangerous.
2599    //
2600    // Our first line of defense is the borrow checker: we have a mutable borrow, so nothing
2601    // can access the ThinVec while we exist. As long as we make sure the ThinVec is in a valid
2602    // state again before we release the borrow, everything should be A-OK! We do this cleanup
2603    // in our Drop impl.
2604    //
2605    // Unfortunately, that's unsound, because mem::forget exists and The Leakpocalypse Is Real.
2606    // So we can't actually guarantee our destructor runs before our borrow expires. Thankfully
2607    // this isn't fatal: we can just set the ThinVec's len to 0 at the start, so if anyone
2608    // leaks the Drain, we just leak everything the ThinVec contained out of spite! If they
2609    // *don't* leak us then we can properly repair the len in our Drop impl. This is known
2610    // as "leak amplification", and is the same approach std uses.
2611    //
2612    // But we can do slightly better than setting the len to 0! The drain breaks us up into
2613    // these parts:
2614    //
2615    // ```text
2616    //
2617    // [A, B, C, D, E, F, G, H, _, _]
2618    //  ____  __________  ____  ____
2619    //   |         |        |     |
2620    // prefix    drain     tail  spare-cap
2621    // ```
2622    //
2623    // As the drain iterator is consumed from both ends (DoubleEnded!), we'll start to look
2624    // like this:
2625    //
2626    // ```text
2627    // [A, B, _, _, E, _, G, H, _, _]
2628    //  ____  __________  ____  ____
2629    //   |         |        |     |
2630    // prefix    drain     tail   spare-cap
2631    // ```
2632    //
2633    // Note that the prefix is always valid and untouched, as such we can set the len
2634    // to the prefix when doing leak-amplification. As a bonus, we can use this value
2635    // to remember where the drain range starts. At the end we'll look like this
2636    // (we exhaust ourselves in our Drop impl):
2637    //
2638    // ```text
2639    // [A, B, _, _, _, _, G, H, _, _]
2640    // _____  __________  _____ ____
2641    //   |         |        |     |
2642    //  len      drain     tail  spare-cap
2643    // ```
2644    //
2645    // And need to become this:
2646    //
2647    // ```text
2648    // [A, B, G, H, _, _, _, _, _, _]
2649    // ___________  ________________
2650    //     |               |
2651    //    len          spare-cap
2652    // ```
2653    //
2654    // All this requires is moving the tail back to the prefix (stored in `len`)
2655    // and setting `len` to `len + tail_len` to undo the leak amplification.
2656    /// An iterator over the elements we're removing.
2657    ///
2658    /// As we go we'll be `read`ing out of the shared refs yielded by this.
2659    /// It's ok to use Iter here because it promises to only take refs to the parts
2660    /// we haven't yielded yet.
2661    iter: Iter<'a, T>,
2662    /// The actual ThinVec, which we need to hold onto to undo the leak amplification
2663    /// and backshift the tail into place. This should only be accessed when we're
2664    /// completely done with the Iter in the `drop` impl of this type (or miri will get mad).
2665    ///
2666    /// Since we set the `len` of this to be before `Iter`, we can use that `len`
2667    /// to retrieve the index of the start of the drain range later.
2668    vec: NonNull<ThinVec<T>>,
2669    /// The one-past-the-end index of the drain range, or equivalently the start of the tail.
2670    end: usize,
2671    /// The length of the tail.
2672    tail: usize,
2673}
2674
2675impl<'a, T> Iterator for Drain<'a, T> {
2676    type Item = T;
2677    fn next(&mut self) -> Option<T> {
2678        self.iter.next().map(|x| unsafe { ptr::read(x) })
2679    }
2680
2681    fn size_hint(&self) -> (usize, Option<usize>) {
2682        self.iter.size_hint()
2683    }
2684}
2685
2686impl<'a, T> DoubleEndedIterator for Drain<'a, T> {
2687    fn next_back(&mut self) -> Option<T> {
2688        self.iter.next_back().map(|x| unsafe { ptr::read(x) })
2689    }
2690}
2691
2692impl<'a, T> ExactSizeIterator for Drain<'a, T> {}
2693
2694// SAFETY: we need to keep track of this perfectly Or Else anyway!
2695#[cfg(feature = "unstable")]
2696unsafe impl<T> core::iter::TrustedLen for Drain<'_, T> {}
2697
2698impl<T> core::iter::FusedIterator for Drain<'_, T> {}
2699
2700impl<'a, T> Drop for Drain<'a, T> {
2701    fn drop(&mut self) {
2702        // Consume the rest of the iterator.
2703        for _ in self.by_ref() {}
2704
2705        // Move the tail over the drained items, and update the length.
2706        unsafe {
2707            let vec = self.vec.as_mut();
2708
2709            // Don't mutate the empty singleton!
2710            if !vec.is_singleton() {
2711                let old_len = vec.len();
2712                let start = vec.data_raw().add(old_len);
2713                let end = vec.data_raw().add(self.end);
2714                ptr::copy(end, start, self.tail);
2715                vec.set_len_non_singleton(old_len + self.tail);
2716            }
2717        }
2718    }
2719}
2720
2721impl<T: fmt::Debug> fmt::Debug for Drain<'_, T> {
2722    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2723        f.debug_tuple("Drain").field(&self.iter.as_slice()).finish()
2724    }
2725}
2726
2727impl<'a, T> Drain<'a, T> {
2728    /// Returns the remaining items of this iterator as a slice.
2729    ///
2730    /// # Examples
2731    ///
2732    /// ```
2733    /// use thin_vec::thin_vec;
2734    ///
2735    /// let mut vec = thin_vec!['a', 'b', 'c'];
2736    /// let mut drain = vec.drain(..);
2737    /// assert_eq!(drain.as_slice(), &['a', 'b', 'c']);
2738    /// let _ = drain.next().unwrap();
2739    /// assert_eq!(drain.as_slice(), &['b', 'c']);
2740    /// ```
2741    #[must_use]
2742    pub fn as_slice(&self) -> &[T] {
2743        // SAFETY: this is A-OK because the elements that the underlying
2744        // iterator still points at are still logically initialized and contiguous.
2745        self.iter.as_slice()
2746    }
2747}
2748
2749impl<'a, T> AsRef<[T]> for Drain<'a, T> {
2750    fn as_ref(&self) -> &[T] {
2751        self.as_slice()
2752    }
2753}
2754
2755/// A splicing iterator for `ThinVec`.
2756///
2757/// This struct is created by [`ThinVec::splice`][].
2758/// See its documentation for more.
2759///
2760/// # Example
2761///
2762/// ```
2763/// use thin_vec::thin_vec;
2764///
2765/// let mut v = thin_vec![0, 1, 2];
2766/// let new = [7, 8];
2767/// let iter: thin_vec::Splice<_> = v.splice(1.., new);
2768/// ```
2769#[derive(Debug)]
2770pub struct Splice<'a, I: Iterator + 'a> {
2771    drain: Drain<'a, I::Item>,
2772    replace_with: I,
2773}
2774
2775impl<I: Iterator> Iterator for Splice<'_, I> {
2776    type Item = I::Item;
2777
2778    fn next(&mut self) -> Option<Self::Item> {
2779        self.drain.next()
2780    }
2781
2782    fn size_hint(&self) -> (usize, Option<usize>) {
2783        self.drain.size_hint()
2784    }
2785}
2786
2787impl<I: Iterator> DoubleEndedIterator for Splice<'_, I> {
2788    fn next_back(&mut self) -> Option<Self::Item> {
2789        self.drain.next_back()
2790    }
2791}
2792
2793impl<I: Iterator> ExactSizeIterator for Splice<'_, I> {}
2794
2795impl<I: Iterator> Drop for Splice<'_, I> {
2796    fn drop(&mut self) {
2797        // Ensure we've fully drained out the range
2798        self.drain.by_ref().for_each(drop);
2799
2800        unsafe {
2801            // If there's no tail elements, then the inner ThinVec is already
2802            // correct and we can just extend it like normal.
2803            if self.drain.tail == 0 {
2804                self.drain.vec.as_mut().extend(self.replace_with.by_ref());
2805                return;
2806            }
2807
2808            // First fill the range left by drain().
2809            if !self.drain.fill(&mut self.replace_with) {
2810                return;
2811            }
2812
2813            // There may be more elements. Use the lower bound as an estimate.
2814            let (lower_bound, _upper_bound) = self.replace_with.size_hint();
2815            if lower_bound > 0 {
2816                self.drain.move_tail(lower_bound);
2817                if !self.drain.fill(&mut self.replace_with) {
2818                    return;
2819                }
2820            }
2821
2822            // Collect any remaining elements.
2823            // This is a zero-length vector which does not allocate if `lower_bound` was exact.
2824            let mut collected = self
2825                .replace_with
2826                .by_ref()
2827                .collect::<Vec<I::Item>>()
2828                .into_iter();
2829            // Now we have an exact count.
2830            if collected.len() > 0 {
2831                self.drain.move_tail(collected.len());
2832                let filled = self.drain.fill(&mut collected);
2833                debug_assert!(filled);
2834                debug_assert_eq!(collected.len(), 0);
2835            }
2836        }
2837        // Let `Drain::drop` move the tail back if necessary and restore `vec.len`.
2838    }
2839}
2840
2841#[cfg(feature = "gecko-ffi")]
2842#[repr(C, align(8))]
2843struct AutoBuffer<T, const N: usize> {
2844    header: Header,
2845    buffer: mem::MaybeUninit<[T; N]>,
2846}
2847
2848#[doc(hidden)]
2849#[cfg(feature = "gecko-ffi")]
2850#[repr(C)]
2851pub struct AutoThinVec<T, const N: usize> {
2852    inner: ThinVec<T>,
2853    buffer: AutoBuffer<T, N>,
2854    _pinned: std::marker::PhantomPinned,
2855}
2856
2857#[cfg(feature = "gecko-ffi")]
2858impl<T, const N: usize> AutoThinVec<T, N> {
2859    /// Implementation detail for the auto_thin_vec macro.
2860    #[inline]
2861    #[doc(hidden)]
2862    pub fn new_unpinned() -> Self {
2863        // This condition is hard-coded in nsTArray.h
2864        assert!(
2865            std::mem::align_of::<T>() <= 8,
2866            "Can't handle alignments greater than 8"
2867        );
2868        assert_eq!(std::mem::offset_of!(Self, buffer), AUTO_ARRAY_HEADER_OFFSET);
2869        Self {
2870            inner: ThinVec::new(),
2871            buffer: AutoBuffer {
2872                header: Header {
2873                    _len: 0,
2874                    _cap: pack_capacity_and_auto(N as SizeType, true),
2875                },
2876                buffer: mem::MaybeUninit::uninit(),
2877            },
2878            _pinned: std::marker::PhantomPinned,
2879        }
2880    }
2881
2882    /// Returns a raw pointer to the inner ThinVec. Note that if you dereference it from rust, you
2883    /// need to make sure not to move the ThinVec manually via something like
2884    /// `std::mem::take(&mut auto_vec)`.
2885    pub fn as_mut_ptr(self: std::pin::Pin<&mut Self>) -> *mut ThinVec<T> {
2886        debug_assert!(self.is_auto_array());
2887        unsafe { &mut self.get_unchecked_mut().inner }
2888    }
2889
2890    #[inline]
2891    pub unsafe fn shrink_to_fit_known_singleton(self: std::pin::Pin<&mut Self>) {
2892        debug_assert!(self.is_singleton());
2893        let this = unsafe { self.get_unchecked_mut() };
2894        this.buffer.header.set_len(0);
2895        // TODO(emilio): Use NonNull::from_mut when msrv allows.
2896        this.inner.ptr = NonNull::new_unchecked(&mut this.buffer.header);
2897        debug_assert!(this.inner.is_auto_array());
2898        debug_assert!(this.inner.uses_stack_allocated_buffer());
2899    }
2900
2901    pub fn shrink_to_fit(self: std::pin::Pin<&mut Self>) {
2902        let this = unsafe { self.get_unchecked_mut() };
2903        this.inner.shrink_to_fit();
2904        debug_assert!(this.inner.is_auto_array());
2905    }
2906}
2907
2908// NOTE(emilio): DerefMut wouldn't be safe, see the comment in as_mut_ptr.
2909#[cfg(feature = "gecko-ffi")]
2910impl<T, const N: usize> Deref for AutoThinVec<T, N> {
2911    type Target = ThinVec<T>;
2912
2913    fn deref(&self) -> &Self::Target {
2914        &self.inner
2915    }
2916}
2917
2918/// Create a ThinVec<$ty> named `$name`, with capacity for `$cap` inline elements.
2919///
2920/// TODO(emilio): This would be a lot more convenient to use with super let, see
2921/// <https://github.com/rust-lang/rust/issues/139076>
2922#[cfg(feature = "gecko-ffi")]
2923#[macro_export]
2924macro_rules! auto_thin_vec {
2925    (let $name:ident : [$ty:ty; $cap:literal]) => {
2926        let auto_vec = $crate::AutoThinVec::<$ty, $cap>::new_unpinned();
2927        let mut $name = core::pin::pin!(auto_vec);
2928        unsafe { $name.as_mut().shrink_to_fit_known_singleton() };
2929    };
2930}
2931
2932/// Private helper methods for `Splice::drop`
2933impl<T> Drain<'_, T> {
2934    /// The range from `self.vec.len` to `self.tail_start` contains elements
2935    /// that have been moved out.
2936    /// Fill that range as much as possible with new elements from the `replace_with` iterator.
2937    /// Returns `true` if we filled the entire range. (`replace_with.next()` didn’t return `None`.)
2938    unsafe fn fill<I: Iterator<Item = T>>(&mut self, replace_with: &mut I) -> bool {
2939        let vec = unsafe { self.vec.as_mut() };
2940        let range_start = vec.len();
2941        let range_end = self.end;
2942        let range_slice = unsafe {
2943            slice::from_raw_parts_mut(vec.data_raw().add(range_start), range_end - range_start)
2944        };
2945
2946        for place in range_slice {
2947            if let Some(new_item) = replace_with.next() {
2948                unsafe { ptr::write(place, new_item) };
2949                vec.set_len(vec.len() + 1);
2950            } else {
2951                return false;
2952            }
2953        }
2954        true
2955    }
2956
2957    /// Makes room for inserting more elements before the tail.
2958    unsafe fn move_tail(&mut self, additional: usize) {
2959        let vec = unsafe { self.vec.as_mut() };
2960        let len = self.end + self.tail;
2961        vec.reserve(len.checked_add(additional).unwrap_cap_overflow());
2962
2963        let new_tail_start = self.end + additional;
2964        unsafe {
2965            let src = vec.data_raw().add(self.end);
2966            let dst = vec.data_raw().add(new_tail_start);
2967            ptr::copy(src, dst, self.tail);
2968        }
2969        self.end = new_tail_start;
2970    }
2971}
2972
2973/// An iterator for [`ThinVec`] which uses a closure to determine if an element should be removed.
2974#[must_use = "iterators are lazy and do nothing unless consumed"]
2975pub struct ExtractIf<'a, T, F> {
2976    vec: &'a mut ThinVec<T>,
2977    /// The index of the item that will be inspected by the next call to `next`.
2978    idx: usize,
2979    /// Elements at and beyond this point will be retained. Must be equal or smaller than `old_len`.
2980    end: usize,
2981    /// The number of items that have been drained (removed) thus far.
2982    del: usize,
2983    /// The original length of `vec` prior to draining.
2984    old_len: usize,
2985    /// The filter test predicate.
2986    pred: F,
2987}
2988
2989impl<T, F> Iterator for ExtractIf<'_, T, F>
2990where
2991    F: FnMut(&mut T) -> bool,
2992{
2993    type Item = T;
2994
2995    fn next(&mut self) -> Option<T> {
2996        unsafe {
2997            let v = self.vec.data_raw();
2998            while self.idx < self.end {
2999                let i = self.idx;
3000                let drained = (self.pred)(&mut *v.add(i));
3001                // Update the index *after* the predicate is called. If the index
3002                // is updated prior and the predicate panics, the element at this
3003                // index would be leaked.
3004                self.idx += 1;
3005                if drained {
3006                    self.del += 1;
3007                    return Some(ptr::read(v.add(i)));
3008                } else if self.del > 0 {
3009                    let del = self.del;
3010                    let src: *const T = v.add(i);
3011                    let dst: *mut T = v.add(i - del);
3012                    ptr::copy_nonoverlapping(src, dst, 1);
3013                }
3014            }
3015            None
3016        }
3017    }
3018
3019    fn size_hint(&self) -> (usize, Option<usize>) {
3020        (0, Some(self.end - self.idx))
3021    }
3022}
3023
3024impl<A, F> Drop for ExtractIf<'_, A, F> {
3025    fn drop(&mut self) {
3026        unsafe {
3027            if self.idx < self.old_len && self.del > 0 {
3028                // This is a pretty messed up state, and there isn't really an
3029                // obviously right thing to do. We don't want to keep trying
3030                // to execute `pred`, so we just backshift all the unprocessed
3031                // elements and tell the vec that they still exist. The backshift
3032                // is required to prevent a double-drop of the last successfully
3033                // drained item prior to a panic in the predicate.
3034                let ptr = self.vec.data_raw();
3035                let src = ptr.add(self.idx);
3036                let dst = src.sub(self.del);
3037                let tail_len = self.old_len - self.idx;
3038                src.copy_to(dst, tail_len);
3039            }
3040
3041            self.vec.set_len(self.old_len - self.del);
3042        }
3043    }
3044}
3045
3046/// Write is implemented for `ThinVec<u8>` by appending to the vector.
3047/// The vector will grow as needed.
3048/// This implementation is identical to the one for `Vec<u8>`.
3049#[cfg(feature = "std")]
3050impl std::io::Write for ThinVec<u8> {
3051    #[inline]
3052    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
3053        self.extend_from_slice(buf);
3054        Ok(buf.len())
3055    }
3056
3057    #[inline]
3058    fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> {
3059        self.extend_from_slice(buf);
3060        Ok(())
3061    }
3062
3063    #[inline]
3064    fn flush(&mut self) -> std::io::Result<()> {
3065        Ok(())
3066    }
3067}
3068
3069// TODO: a million Index impls
3070
3071#[cfg(test)]
3072mod tests {
3073    use super::{ThinVec, MAX_CAP};
3074    use crate::alloc::{string::ToString, vec};
3075
3076    #[test]
3077    fn test_size_of() {
3078        use core::mem::size_of;
3079        assert_eq!(size_of::<ThinVec<u8>>(), size_of::<&u8>());
3080
3081        assert_eq!(size_of::<Option<ThinVec<u8>>>(), size_of::<&u8>());
3082    }
3083
3084    #[test]
3085    fn test_drop_empty() {
3086        ThinVec::<u8>::new();
3087    }
3088
3089    #[test]
3090    fn test_data_ptr_alignment() {
3091        let v = ThinVec::<u16>::new();
3092        assert!(v.data_raw() as usize % core::mem::align_of::<u16>() == 0);
3093
3094        let v = ThinVec::<u32>::new();
3095        assert!(v.data_raw() as usize % core::mem::align_of::<u32>() == 0);
3096
3097        let v = ThinVec::<u64>::new();
3098        assert!(v.data_raw() as usize % core::mem::align_of::<u64>() == 0);
3099    }
3100
3101    #[test]
3102    #[cfg_attr(feature = "gecko-ffi", should_panic)]
3103    fn test_overaligned_type_is_rejected_for_gecko_ffi_mode() {
3104        #[repr(align(16))]
3105        struct Align16(u8);
3106
3107        let v = ThinVec::<Align16>::new();
3108        assert!(v.data_raw() as usize % 16 == 0);
3109    }
3110
3111    #[test]
3112    fn test_partial_eq() {
3113        assert_eq!(thin_vec![0], thin_vec![0]);
3114        assert_ne!(thin_vec![0], thin_vec![1]);
3115        assert_eq!(thin_vec![1, 2, 3], vec![1, 2, 3]);
3116    }
3117
3118    #[test]
3119    fn test_alloc() {
3120        let mut v = ThinVec::new();
3121        assert!(!v.has_allocation());
3122        v.push(1);
3123        assert!(v.has_allocation());
3124        v.pop();
3125        assert!(v.has_allocation());
3126        v.shrink_to_fit();
3127        assert!(!v.has_allocation());
3128        v.reserve(64);
3129        assert!(v.has_allocation());
3130        v = ThinVec::with_capacity(64);
3131        assert!(v.has_allocation());
3132        v = ThinVec::with_capacity(0);
3133        assert!(!v.has_allocation());
3134    }
3135
3136    #[test]
3137    fn test_drain_items() {
3138        let mut vec = thin_vec![1, 2, 3];
3139        let mut vec2 = thin_vec![];
3140        for i in vec.drain(..) {
3141            vec2.push(i);
3142        }
3143        assert_eq!(vec, []);
3144        assert_eq!(vec2, [1, 2, 3]);
3145    }
3146
3147    #[test]
3148    fn test_drain_items_reverse() {
3149        let mut vec = thin_vec![1, 2, 3];
3150        let mut vec2 = thin_vec![];
3151        for i in vec.drain(..).rev() {
3152            vec2.push(i);
3153        }
3154        assert_eq!(vec, []);
3155        assert_eq!(vec2, [3, 2, 1]);
3156    }
3157
3158    #[test]
3159    fn test_drain_items_zero_sized() {
3160        let mut vec = thin_vec![(), (), ()];
3161        let mut vec2 = thin_vec![];
3162        for i in vec.drain(..) {
3163            vec2.push(i);
3164        }
3165        assert_eq!(vec, []);
3166        assert_eq!(vec2, [(), (), ()]);
3167    }
3168
3169    #[test]
3170    #[should_panic]
3171    fn test_drain_out_of_bounds() {
3172        let mut v = thin_vec![1, 2, 3, 4, 5];
3173        v.drain(5..6);
3174    }
3175
3176    #[test]
3177    fn test_drain_range() {
3178        let mut v = thin_vec![1, 2, 3, 4, 5];
3179        for _ in v.drain(4..) {}
3180        assert_eq!(v, &[1, 2, 3, 4]);
3181
3182        let mut v: ThinVec<_> = (1..6).map(|x| x.to_string()).collect();
3183        for _ in v.drain(1..4) {}
3184        assert_eq!(v, &[1.to_string(), 5.to_string()]);
3185
3186        let mut v: ThinVec<_> = (1..6).map(|x| x.to_string()).collect();
3187        for _ in v.drain(1..4).rev() {}
3188        assert_eq!(v, &[1.to_string(), 5.to_string()]);
3189
3190        let mut v: ThinVec<_> = thin_vec![(); 5];
3191        for _ in v.drain(1..4).rev() {}
3192        assert_eq!(v, &[(), ()]);
3193    }
3194
3195    #[test]
3196    fn test_drain_max_vec_size() {
3197        let mut v = ThinVec::<()>::with_capacity(MAX_CAP);
3198        unsafe {
3199            v.set_len(MAX_CAP);
3200        }
3201        for _ in v.drain(MAX_CAP - 1..) {}
3202        assert_eq!(v.len(), MAX_CAP - 1);
3203    }
3204
3205    #[test]
3206    fn test_clear() {
3207        let mut v = ThinVec::<i32>::new();
3208        assert_eq!(v.len(), 0);
3209        assert_eq!(v.capacity(), 0);
3210        assert_eq!(&v[..], &[]);
3211
3212        v.clear();
3213        assert_eq!(v.len(), 0);
3214        assert_eq!(v.capacity(), 0);
3215        assert_eq!(&v[..], &[]);
3216
3217        v.push(1);
3218        v.push(2);
3219        assert_eq!(v.len(), 2);
3220        assert!(v.capacity() >= 2);
3221        assert_eq!(&v[..], &[1, 2]);
3222
3223        v.clear();
3224        assert_eq!(v.len(), 0);
3225        assert!(v.capacity() >= 2);
3226        assert_eq!(&v[..], &[]);
3227
3228        v.push(3);
3229        v.push(4);
3230        assert_eq!(v.len(), 2);
3231        assert!(v.capacity() >= 2);
3232        assert_eq!(&v[..], &[3, 4]);
3233
3234        v.clear();
3235        assert_eq!(v.len(), 0);
3236        assert!(v.capacity() >= 2);
3237        assert_eq!(&v[..], &[]);
3238
3239        v.clear();
3240        assert_eq!(v.len(), 0);
3241        assert!(v.capacity() >= 2);
3242        assert_eq!(&v[..], &[]);
3243    }
3244
3245    #[test]
3246    fn test_empty_singleton_torture() {
3247        {
3248            let mut v = ThinVec::<i32>::new();
3249            assert_eq!(v.len(), 0);
3250            assert_eq!(v.capacity(), 0);
3251            assert!(v.is_empty());
3252            assert_eq!(&v[..], &[]);
3253            assert_eq!(&mut v[..], &mut []);
3254
3255            assert_eq!(v.pop(), None);
3256            assert_eq!(v.len(), 0);
3257            assert_eq!(v.capacity(), 0);
3258            assert_eq!(&v[..], &[]);
3259        }
3260
3261        {
3262            let v = ThinVec::<i32>::new();
3263            assert_eq!(v.into_iter().count(), 0);
3264
3265            let v = ThinVec::<i32>::new();
3266            #[allow(clippy::never_loop)]
3267            for _ in v.into_iter() {
3268                unreachable!();
3269            }
3270        }
3271
3272        {
3273            let mut v = ThinVec::<i32>::new();
3274            assert_eq!(v.drain(..).len(), 0);
3275
3276            #[allow(clippy::never_loop)]
3277            for _ in v.drain(..) {
3278                unreachable!()
3279            }
3280
3281            assert_eq!(v.len(), 0);
3282            assert_eq!(v.capacity(), 0);
3283            assert_eq!(&v[..], &[]);
3284        }
3285
3286        {
3287            let mut v = ThinVec::<i32>::new();
3288            assert_eq!(v.splice(.., []).len(), 0);
3289
3290            #[allow(clippy::never_loop)]
3291            for _ in v.splice(.., []) {
3292                unreachable!()
3293            }
3294
3295            assert_eq!(v.len(), 0);
3296            assert_eq!(v.capacity(), 0);
3297            assert_eq!(&v[..], &[]);
3298        }
3299
3300        {
3301            let mut v = ThinVec::<i32>::new();
3302            v.truncate(1);
3303            assert_eq!(v.len(), 0);
3304            assert_eq!(v.capacity(), 0);
3305            assert_eq!(&v[..], &[]);
3306
3307            v.truncate(0);
3308            assert_eq!(v.len(), 0);
3309            assert_eq!(v.capacity(), 0);
3310            assert_eq!(&v[..], &[]);
3311        }
3312
3313        {
3314            let mut v = ThinVec::<i32>::new();
3315            v.shrink_to_fit();
3316            assert_eq!(v.len(), 0);
3317            assert_eq!(v.capacity(), 0);
3318            assert_eq!(&v[..], &[]);
3319        }
3320
3321        {
3322            let mut v = ThinVec::<i32>::new();
3323            let new = v.split_off(0);
3324            assert_eq!(v.len(), 0);
3325            assert_eq!(v.capacity(), 0);
3326            assert_eq!(&v[..], &[]);
3327
3328            assert_eq!(new.len(), 0);
3329            assert_eq!(new.capacity(), 0);
3330            assert_eq!(&new[..], &[]);
3331        }
3332
3333        {
3334            let mut v = ThinVec::<i32>::new();
3335            let mut other = ThinVec::<i32>::new();
3336            v.append(&mut other);
3337
3338            assert_eq!(v.len(), 0);
3339            assert_eq!(v.capacity(), 0);
3340            assert_eq!(&v[..], &[]);
3341
3342            assert_eq!(other.len(), 0);
3343            assert_eq!(other.capacity(), 0);
3344            assert_eq!(&other[..], &[]);
3345        }
3346
3347        {
3348            let mut v = ThinVec::<i32>::new();
3349            v.reserve(0);
3350
3351            assert_eq!(v.len(), 0);
3352            assert_eq!(v.capacity(), 0);
3353            assert_eq!(&v[..], &[]);
3354        }
3355
3356        {
3357            let mut v = ThinVec::<i32>::new();
3358            v.reserve_exact(0);
3359
3360            assert_eq!(v.len(), 0);
3361            assert_eq!(v.capacity(), 0);
3362            assert_eq!(&v[..], &[]);
3363        }
3364
3365        {
3366            let mut v = ThinVec::<i32>::new();
3367            v.reserve(0);
3368
3369            assert_eq!(v.len(), 0);
3370            assert_eq!(v.capacity(), 0);
3371            assert_eq!(&v[..], &[]);
3372        }
3373
3374        {
3375            let v = ThinVec::<i32>::with_capacity(0);
3376
3377            assert_eq!(v.len(), 0);
3378            assert_eq!(v.capacity(), 0);
3379            assert_eq!(&v[..], &[]);
3380        }
3381
3382        {
3383            let v = ThinVec::<i32>::default();
3384
3385            assert_eq!(v.len(), 0);
3386            assert_eq!(v.capacity(), 0);
3387            assert_eq!(&v[..], &[]);
3388        }
3389
3390        {
3391            let mut v = ThinVec::<i32>::new();
3392            v.retain(|_| unreachable!());
3393
3394            assert_eq!(v.len(), 0);
3395            assert_eq!(v.capacity(), 0);
3396            assert_eq!(&v[..], &[]);
3397        }
3398
3399        {
3400            let mut v = ThinVec::<i32>::new();
3401            v.retain_mut(|_| unreachable!());
3402
3403            assert_eq!(v.len(), 0);
3404            assert_eq!(v.capacity(), 0);
3405            assert_eq!(&v[..], &[]);
3406        }
3407
3408        {
3409            let mut v = ThinVec::<i32>::new();
3410            v.dedup_by_key(|x| *x);
3411
3412            assert_eq!(v.len(), 0);
3413            assert_eq!(v.capacity(), 0);
3414            assert_eq!(&v[..], &[]);
3415        }
3416
3417        {
3418            let mut v = ThinVec::<i32>::new();
3419            v.dedup_by(|_, _| unreachable!());
3420
3421            assert_eq!(v.len(), 0);
3422            assert_eq!(v.capacity(), 0);
3423            assert_eq!(&v[..], &[]);
3424        }
3425
3426        {
3427            let v = ThinVec::<i32>::new();
3428            let v = v.clone();
3429
3430            assert_eq!(v.len(), 0);
3431            assert_eq!(v.capacity(), 0);
3432            assert_eq!(&v[..], &[]);
3433        }
3434    }
3435
3436    #[test]
3437    fn test_clone() {
3438        let mut v = ThinVec::<i32>::new();
3439        assert!(v.is_singleton());
3440        v.push(0);
3441        v.pop();
3442        assert!(!v.is_singleton());
3443
3444        let v2 = v.clone();
3445        assert!(v2.is_singleton());
3446    }
3447}
3448
3449#[cfg(test)]
3450mod std_tests {
3451    #![allow(clippy::reversed_empty_ranges)]
3452
3453    use super::*;
3454    use crate::alloc::{
3455        format,
3456        string::{String, ToString},
3457    };
3458    use core::mem::size_of;
3459    use core::usize;
3460
3461    struct DropCounter<'a> {
3462        count: &'a mut u32,
3463    }
3464
3465    impl<'a> Drop for DropCounter<'a> {
3466        fn drop(&mut self) {
3467            *self.count += 1;
3468        }
3469    }
3470
3471    #[test]
3472    fn test_small_vec_struct() {
3473        assert!(size_of::<ThinVec<u8>>() == size_of::<usize>());
3474    }
3475
3476    #[test]
3477    fn test_double_drop() {
3478        struct TwoVec<T> {
3479            x: ThinVec<T>,
3480            y: ThinVec<T>,
3481        }
3482
3483        let (mut count_x, mut count_y) = (0, 0);
3484        {
3485            let mut tv = TwoVec {
3486                x: ThinVec::new(),
3487                y: ThinVec::new(),
3488            };
3489            tv.x.push(DropCounter {
3490                count: &mut count_x,
3491            });
3492            tv.y.push(DropCounter {
3493                count: &mut count_y,
3494            });
3495
3496            // If ThinVec had a drop flag, here is where it would be zeroed.
3497            // Instead, it should rely on its internal state to prevent
3498            // doing anything significant when dropped multiple times.
3499            drop(tv.x);
3500
3501            // Here tv goes out of scope, tv.y should be dropped, but not tv.x.
3502        }
3503
3504        assert_eq!(count_x, 1);
3505        assert_eq!(count_y, 1);
3506    }
3507
3508    #[test]
3509    fn test_reserve() {
3510        let mut v = ThinVec::new();
3511        assert_eq!(v.capacity(), 0);
3512
3513        v.reserve(2);
3514        assert!(v.capacity() >= 2);
3515
3516        for i in 0..16 {
3517            v.push(i);
3518        }
3519
3520        assert!(v.capacity() >= 16);
3521        v.reserve(16);
3522        assert!(v.capacity() >= 32);
3523
3524        v.push(16);
3525
3526        v.reserve(16);
3527        assert!(v.capacity() >= 33)
3528    }
3529
3530    #[test]
3531    fn test_extend() {
3532        let mut v = ThinVec::<usize>::new();
3533        let mut w = ThinVec::new();
3534        v.extend(w.clone());
3535        assert_eq!(v, &[]);
3536
3537        v.extend(0..3);
3538        for i in 0..3 {
3539            w.push(i)
3540        }
3541
3542        assert_eq!(v, w);
3543
3544        v.extend(3..10);
3545        for i in 3..10 {
3546            w.push(i)
3547        }
3548
3549        assert_eq!(v, w);
3550
3551        v.extend(w.clone()); // specializes to `append`
3552        assert!(v.iter().eq(w.iter().chain(w.iter())));
3553
3554        // Zero sized types
3555        #[derive(PartialEq, Debug)]
3556        struct Foo;
3557
3558        let mut a = ThinVec::new();
3559        let b = thin_vec![Foo, Foo];
3560
3561        a.extend(b);
3562        assert_eq!(a, &[Foo, Foo]);
3563
3564        // Double drop
3565        let mut count_x = 0;
3566        {
3567            let mut x = ThinVec::new();
3568            let y = thin_vec![DropCounter {
3569                count: &mut count_x
3570            }];
3571            x.extend(y);
3572        }
3573
3574        assert_eq!(count_x, 1);
3575    }
3576
3577    /* TODO: implement extend for Iter<&Copy>
3578        #[test]
3579        fn test_extend_ref() {
3580            let mut v = thin_vec![1, 2];
3581            v.extend(&[3, 4, 5]);
3582
3583            assert_eq!(v.len(), 5);
3584            assert_eq!(v, [1, 2, 3, 4, 5]);
3585
3586            let w = thin_vec![6, 7];
3587            v.extend(&w);
3588
3589            assert_eq!(v.len(), 7);
3590            assert_eq!(v, [1, 2, 3, 4, 5, 6, 7]);
3591        }
3592    */
3593
3594    #[test]
3595    fn test_slice_from_mut() {
3596        let mut values = thin_vec![1, 2, 3, 4, 5];
3597        {
3598            let slice = &mut values[2..];
3599            assert!(slice == [3, 4, 5]);
3600            for p in slice {
3601                *p += 2;
3602            }
3603        }
3604
3605        assert!(values == [1, 2, 5, 6, 7]);
3606    }
3607
3608    #[test]
3609    fn test_slice_to_mut() {
3610        let mut values = thin_vec![1, 2, 3, 4, 5];
3611        {
3612            let slice = &mut values[..2];
3613            assert!(slice == [1, 2]);
3614            for p in slice {
3615                *p += 1;
3616            }
3617        }
3618
3619        assert!(values == [2, 3, 3, 4, 5]);
3620    }
3621
3622    #[test]
3623    fn test_split_at_mut() {
3624        let mut values = thin_vec![1, 2, 3, 4, 5];
3625        {
3626            let (left, right) = values.split_at_mut(2);
3627            {
3628                let left: &[_] = left;
3629                assert!(left[..left.len()] == [1, 2]);
3630            }
3631            for p in left {
3632                *p += 1;
3633            }
3634
3635            {
3636                let right: &[_] = right;
3637                assert!(right[..right.len()] == [3, 4, 5]);
3638            }
3639            for p in right {
3640                *p += 2;
3641            }
3642        }
3643
3644        assert_eq!(values, [2, 3, 5, 6, 7]);
3645    }
3646
3647    #[test]
3648    fn test_clone() {
3649        let v: ThinVec<i32> = thin_vec![];
3650        let w = thin_vec![1, 2, 3];
3651
3652        assert_eq!(v, v.clone());
3653
3654        let z = w.clone();
3655        assert_eq!(w, z);
3656        // they should be disjoint in memory.
3657        assert!(w.as_ptr() != z.as_ptr())
3658    }
3659
3660    #[test]
3661    fn test_clone_from() {
3662        let mut v = thin_vec![];
3663        let three: ThinVec<Box<_>> = thin_vec![Box::new(1), Box::new(2), Box::new(3)];
3664        let two: ThinVec<Box<_>> = thin_vec![Box::new(4), Box::new(5)];
3665        // zero, long
3666        v.clone_from(&three);
3667        assert_eq!(v, three);
3668
3669        // equal
3670        v.clone_from(&three);
3671        assert_eq!(v, three);
3672
3673        // long, short
3674        v.clone_from(&two);
3675        assert_eq!(v, two);
3676
3677        // short, long
3678        v.clone_from(&three);
3679        assert_eq!(v, three)
3680    }
3681
3682    #[test]
3683    fn test_retain() {
3684        let mut vec = thin_vec![1, 2, 3, 4];
3685        vec.retain(|&x| x % 2 == 0);
3686        assert_eq!(vec, [2, 4]);
3687    }
3688
3689    #[test]
3690    fn test_retain_mut() {
3691        let mut vec = thin_vec![9, 9, 9, 9];
3692        let mut i = 0;
3693        vec.retain_mut(|x| {
3694            i += 1;
3695            *x = i;
3696            i != 4
3697        });
3698        assert_eq!(vec, [1, 2, 3]);
3699    }
3700
3701    #[test]
3702    fn test_dedup() {
3703        fn case(a: ThinVec<i32>, b: ThinVec<i32>) {
3704            let mut v = a;
3705            v.dedup();
3706            assert_eq!(v, b);
3707        }
3708        case(thin_vec![], thin_vec![]);
3709        case(thin_vec![1], thin_vec![1]);
3710        case(thin_vec![1, 1], thin_vec![1]);
3711        case(thin_vec![1, 2, 3], thin_vec![1, 2, 3]);
3712        case(thin_vec![1, 1, 2, 3], thin_vec![1, 2, 3]);
3713        case(thin_vec![1, 2, 2, 3], thin_vec![1, 2, 3]);
3714        case(thin_vec![1, 2, 3, 3], thin_vec![1, 2, 3]);
3715        case(thin_vec![1, 1, 2, 2, 2, 3, 3], thin_vec![1, 2, 3]);
3716    }
3717
3718    #[test]
3719    fn test_dedup_by_key() {
3720        fn case(a: ThinVec<i32>, b: ThinVec<i32>) {
3721            let mut v = a;
3722            v.dedup_by_key(|i| *i / 10);
3723            assert_eq!(v, b);
3724        }
3725        case(thin_vec![], thin_vec![]);
3726        case(thin_vec![10], thin_vec![10]);
3727        case(thin_vec![10, 11], thin_vec![10]);
3728        case(thin_vec![10, 20, 30], thin_vec![10, 20, 30]);
3729        case(thin_vec![10, 11, 20, 30], thin_vec![10, 20, 30]);
3730        case(thin_vec![10, 20, 21, 30], thin_vec![10, 20, 30]);
3731        case(thin_vec![10, 20, 30, 31], thin_vec![10, 20, 30]);
3732        case(thin_vec![10, 11, 20, 21, 22, 30, 31], thin_vec![10, 20, 30]);
3733    }
3734
3735    #[test]
3736    fn test_dedup_by() {
3737        let mut vec = thin_vec!["foo", "bar", "Bar", "baz", "bar"];
3738        vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
3739
3740        assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
3741
3742        let mut vec = thin_vec![("foo", 1), ("foo", 2), ("bar", 3), ("bar", 4), ("bar", 5)];
3743        vec.dedup_by(|a, b| {
3744            a.0 == b.0 && {
3745                b.1 += a.1;
3746                true
3747            }
3748        });
3749
3750        assert_eq!(vec, [("foo", 3), ("bar", 12)]);
3751    }
3752
3753    #[test]
3754    fn test_dedup_unique() {
3755        let mut v0: ThinVec<Box<_>> = thin_vec![Box::new(1), Box::new(1), Box::new(2), Box::new(3)];
3756        v0.dedup();
3757        let mut v1: ThinVec<Box<_>> = thin_vec![Box::new(1), Box::new(2), Box::new(2), Box::new(3)];
3758        v1.dedup();
3759        let mut v2: ThinVec<Box<_>> = thin_vec![Box::new(1), Box::new(2), Box::new(3), Box::new(3)];
3760        v2.dedup();
3761        // If the boxed pointers were leaked or otherwise misused, valgrind
3762        // and/or rt should raise errors.
3763    }
3764
3765    #[test]
3766    fn zero_sized_values() {
3767        let mut v = ThinVec::new();
3768        assert_eq!(v.len(), 0);
3769        v.push(());
3770        assert_eq!(v.len(), 1);
3771        v.push(());
3772        assert_eq!(v.len(), 2);
3773        assert_eq!(v.pop(), Some(()));
3774        assert_eq!(v.pop(), Some(()));
3775        assert_eq!(v.pop(), None);
3776
3777        assert_eq!(v.iter().count(), 0);
3778        v.push(());
3779        assert_eq!(v.iter().count(), 1);
3780        v.push(());
3781        assert_eq!(v.iter().count(), 2);
3782
3783        for &() in &v {}
3784
3785        assert_eq!(v.iter_mut().count(), 2);
3786        v.push(());
3787        assert_eq!(v.iter_mut().count(), 3);
3788        v.push(());
3789        assert_eq!(v.iter_mut().count(), 4);
3790
3791        for &mut () in &mut v {}
3792        unsafe {
3793            v.set_len(0);
3794        }
3795        assert_eq!(v.iter_mut().count(), 0);
3796    }
3797
3798    #[test]
3799    fn test_partition() {
3800        assert_eq!(
3801            thin_vec![].into_iter().partition(|x: &i32| *x < 3),
3802            (thin_vec![], thin_vec![])
3803        );
3804        assert_eq!(
3805            thin_vec![1, 2, 3].into_iter().partition(|x| *x < 4),
3806            (thin_vec![1, 2, 3], thin_vec![])
3807        );
3808        assert_eq!(
3809            thin_vec![1, 2, 3].into_iter().partition(|x| *x < 2),
3810            (thin_vec![1], thin_vec![2, 3])
3811        );
3812        assert_eq!(
3813            thin_vec![1, 2, 3].into_iter().partition(|x| *x < 0),
3814            (thin_vec![], thin_vec![1, 2, 3])
3815        );
3816    }
3817
3818    #[test]
3819    fn test_zip_unzip() {
3820        let z1 = thin_vec![(1, 4), (2, 5), (3, 6)];
3821
3822        let (left, right): (ThinVec<_>, ThinVec<_>) = z1.iter().cloned().unzip();
3823
3824        assert_eq!((1, 4), (left[0], right[0]));
3825        assert_eq!((2, 5), (left[1], right[1]));
3826        assert_eq!((3, 6), (left[2], right[2]));
3827    }
3828
3829    #[test]
3830    fn test_vec_truncate_drop() {
3831        static mut DROPS: u32 = 0;
3832        struct Elem(i32);
3833        impl Drop for Elem {
3834            fn drop(&mut self) {
3835                unsafe {
3836                    DROPS += 1;
3837                }
3838            }
3839        }
3840
3841        let mut v = thin_vec![Elem(1), Elem(2), Elem(3), Elem(4), Elem(5)];
3842        assert_eq!(unsafe { DROPS }, 0);
3843        v.truncate(3);
3844        assert_eq!(unsafe { DROPS }, 2);
3845        v.truncate(0);
3846        assert_eq!(unsafe { DROPS }, 5);
3847    }
3848
3849    #[test]
3850    #[should_panic]
3851    fn test_vec_truncate_fail() {
3852        struct BadElem(i32);
3853        impl Drop for BadElem {
3854            fn drop(&mut self) {
3855                let BadElem(ref mut x) = *self;
3856                if *x == 0xbadbeef {
3857                    panic!("BadElem panic: 0xbadbeef")
3858                }
3859            }
3860        }
3861
3862        let mut v = thin_vec![BadElem(1), BadElem(2), BadElem(0xbadbeef), BadElem(4)];
3863        v.truncate(0);
3864    }
3865
3866    #[test]
3867    fn test_index() {
3868        let vec = thin_vec![1, 2, 3];
3869        assert!(vec[1] == 2);
3870    }
3871
3872    #[test]
3873    #[should_panic]
3874    fn test_index_out_of_bounds() {
3875        let vec = thin_vec![1, 2, 3];
3876        let _ = vec[3];
3877    }
3878
3879    #[test]
3880    #[should_panic]
3881    fn test_slice_out_of_bounds_1() {
3882        let x = thin_vec![1, 2, 3, 4, 5];
3883        let _ = &x[!0..];
3884    }
3885
3886    #[test]
3887    #[should_panic]
3888    fn test_slice_out_of_bounds_2() {
3889        let x = thin_vec![1, 2, 3, 4, 5];
3890        let _ = &x[..6];
3891    }
3892
3893    #[test]
3894    #[should_panic]
3895    fn test_slice_out_of_bounds_3() {
3896        let x = thin_vec![1, 2, 3, 4, 5];
3897        let _ = &x[!0..4];
3898    }
3899
3900    #[test]
3901    #[should_panic]
3902    fn test_slice_out_of_bounds_4() {
3903        let x = thin_vec![1, 2, 3, 4, 5];
3904        let _ = &x[1..6];
3905    }
3906
3907    #[test]
3908    #[should_panic]
3909    fn test_slice_out_of_bounds_5() {
3910        let x = thin_vec![1, 2, 3, 4, 5];
3911        let _ = &x[3..2];
3912    }
3913
3914    #[test]
3915    #[should_panic]
3916    fn test_swap_remove_empty() {
3917        let mut vec = ThinVec::<i32>::new();
3918        vec.swap_remove(0);
3919    }
3920
3921    #[test]
3922    fn test_move_items() {
3923        let vec = thin_vec![1, 2, 3];
3924        let mut vec2 = thin_vec![];
3925        for i in vec {
3926            vec2.push(i);
3927        }
3928        assert_eq!(vec2, [1, 2, 3]);
3929    }
3930
3931    #[test]
3932    fn test_move_items_reverse() {
3933        let vec = thin_vec![1, 2, 3];
3934        let mut vec2 = thin_vec![];
3935        for i in vec.into_iter().rev() {
3936            vec2.push(i);
3937        }
3938        assert_eq!(vec2, [3, 2, 1]);
3939    }
3940
3941    #[test]
3942    fn test_move_items_zero_sized() {
3943        let vec = thin_vec![(), (), ()];
3944        let mut vec2 = thin_vec![];
3945        for i in vec {
3946            vec2.push(i);
3947        }
3948        assert_eq!(vec2, [(), (), ()]);
3949    }
3950
3951    #[test]
3952    fn test_drain_items() {
3953        let mut vec = thin_vec![1, 2, 3];
3954        let mut vec2 = thin_vec![];
3955        for i in vec.drain(..) {
3956            vec2.push(i);
3957        }
3958        assert_eq!(vec, []);
3959        assert_eq!(vec2, [1, 2, 3]);
3960    }
3961
3962    #[test]
3963    fn test_drain_items_reverse() {
3964        let mut vec = thin_vec![1, 2, 3];
3965        let mut vec2 = thin_vec![];
3966        for i in vec.drain(..).rev() {
3967            vec2.push(i);
3968        }
3969        assert_eq!(vec, []);
3970        assert_eq!(vec2, [3, 2, 1]);
3971    }
3972
3973    #[test]
3974    fn test_drain_items_zero_sized() {
3975        let mut vec = thin_vec![(), (), ()];
3976        let mut vec2 = thin_vec![];
3977        for i in vec.drain(..) {
3978            vec2.push(i);
3979        }
3980        assert_eq!(vec, []);
3981        assert_eq!(vec2, [(), (), ()]);
3982    }
3983
3984    #[test]
3985    #[should_panic]
3986    fn test_drain_out_of_bounds() {
3987        let mut v = thin_vec![1, 2, 3, 4, 5];
3988        v.drain(5..6);
3989    }
3990
3991    #[test]
3992    fn test_drain_range() {
3993        let mut v = thin_vec![1, 2, 3, 4, 5];
3994        for _ in v.drain(4..) {}
3995        assert_eq!(v, &[1, 2, 3, 4]);
3996
3997        let mut v: ThinVec<_> = (1..6).map(|x| x.to_string()).collect();
3998        for _ in v.drain(1..4) {}
3999        assert_eq!(v, &[1.to_string(), 5.to_string()]);
4000
4001        let mut v: ThinVec<_> = (1..6).map(|x| x.to_string()).collect();
4002        for _ in v.drain(1..4).rev() {}
4003        assert_eq!(v, &[1.to_string(), 5.to_string()]);
4004
4005        let mut v: ThinVec<_> = thin_vec![(); 5];
4006        for _ in v.drain(1..4).rev() {}
4007        assert_eq!(v, &[(), ()]);
4008    }
4009
4010    #[test]
4011    fn test_drain_inclusive_range() {
4012        let mut v = thin_vec!['a', 'b', 'c', 'd', 'e'];
4013        for _ in v.drain(1..=3) {}
4014        assert_eq!(v, &['a', 'e']);
4015
4016        let mut v: ThinVec<_> = (0..=5).map(|x| x.to_string()).collect();
4017        for _ in v.drain(1..=5) {}
4018        assert_eq!(v, &["0".to_string()]);
4019
4020        let mut v: ThinVec<String> = (0..=5).map(|x| x.to_string()).collect();
4021        for _ in v.drain(0..=5) {}
4022        assert_eq!(v, ThinVec::<String>::new());
4023
4024        let mut v: ThinVec<_> = (0..=5).map(|x| x.to_string()).collect();
4025        for _ in v.drain(0..=3) {}
4026        assert_eq!(v, &["4".to_string(), "5".to_string()]);
4027
4028        let mut v: ThinVec<_> = (0..=1).map(|x| x.to_string()).collect();
4029        for _ in v.drain(..=0) {}
4030        assert_eq!(v, &["1".to_string()]);
4031    }
4032
4033    #[test]
4034    #[cfg(not(feature = "gecko-ffi"))]
4035    fn test_drain_max_vec_size() {
4036        let mut v = ThinVec::<()>::with_capacity(usize::max_value());
4037        unsafe {
4038            v.set_len(usize::max_value());
4039        }
4040        for _ in v.drain(usize::max_value() - 1..) {}
4041        assert_eq!(v.len(), usize::max_value() - 1);
4042
4043        let mut v = ThinVec::<()>::with_capacity(usize::max_value());
4044        unsafe {
4045            v.set_len(usize::max_value());
4046        }
4047        for _ in v.drain(usize::max_value() - 1..=usize::max_value() - 1) {}
4048        assert_eq!(v.len(), usize::max_value() - 1);
4049    }
4050
4051    #[test]
4052    #[should_panic]
4053    fn test_drain_inclusive_out_of_bounds() {
4054        let mut v = thin_vec![1, 2, 3, 4, 5];
4055        v.drain(5..=5);
4056    }
4057
4058    #[test]
4059    fn test_splice() {
4060        let mut v = thin_vec![1, 2, 3, 4, 5];
4061        let a = [10, 11, 12];
4062        v.splice(2..4, a.iter().cloned());
4063        assert_eq!(v, &[1, 2, 10, 11, 12, 5]);
4064        v.splice(1..3, Some(20));
4065        assert_eq!(v, &[1, 20, 11, 12, 5]);
4066    }
4067
4068    #[test]
4069    fn test_splice_inclusive_range() {
4070        let mut v = thin_vec![1, 2, 3, 4, 5];
4071        let a = [10, 11, 12];
4072        let t1: ThinVec<_> = v.splice(2..=3, a.iter().cloned()).collect();
4073        assert_eq!(v, &[1, 2, 10, 11, 12, 5]);
4074        assert_eq!(t1, &[3, 4]);
4075        let t2: ThinVec<_> = v.splice(1..=2, Some(20)).collect();
4076        assert_eq!(v, &[1, 20, 11, 12, 5]);
4077        assert_eq!(t2, &[2, 10]);
4078    }
4079
4080    #[test]
4081    #[should_panic]
4082    fn test_splice_out_of_bounds() {
4083        let mut v = thin_vec![1, 2, 3, 4, 5];
4084        let a = [10, 11, 12];
4085        v.splice(5..6, a.iter().cloned());
4086    }
4087
4088    #[test]
4089    #[should_panic]
4090    fn test_splice_inclusive_out_of_bounds() {
4091        let mut v = thin_vec![1, 2, 3, 4, 5];
4092        let a = [10, 11, 12];
4093        v.splice(5..=5, a.iter().cloned());
4094    }
4095
4096    #[test]
4097    fn test_splice_items_zero_sized() {
4098        let mut vec = thin_vec![(), (), ()];
4099        let vec2 = thin_vec![];
4100        let t: ThinVec<_> = vec.splice(1..2, vec2.iter().cloned()).collect();
4101        assert_eq!(vec, &[(), ()]);
4102        assert_eq!(t, &[()]);
4103    }
4104
4105    #[test]
4106    fn test_splice_unbounded() {
4107        let mut vec = thin_vec![1, 2, 3, 4, 5];
4108        let t: ThinVec<_> = vec.splice(.., None).collect();
4109        assert_eq!(vec, &[]);
4110        assert_eq!(t, &[1, 2, 3, 4, 5]);
4111    }
4112
4113    #[test]
4114    fn test_splice_forget() {
4115        let mut v = thin_vec![1, 2, 3, 4, 5];
4116        let a = [10, 11, 12];
4117        ::core::mem::forget(v.splice(2..4, a.iter().cloned()));
4118        assert_eq!(v, &[1, 2]);
4119    }
4120
4121    #[test]
4122    fn test_splice_from_empty() {
4123        let mut v = thin_vec![];
4124        let a = [10, 11, 12];
4125        v.splice(.., a.iter().cloned());
4126        assert_eq!(v, &[10, 11, 12]);
4127    }
4128
4129    /* probs won't ever impl this
4130        #[test]
4131        fn test_into_boxed_slice() {
4132            let xs = thin_vec![1, 2, 3];
4133            let ys = xs.into_boxed_slice();
4134            assert_eq!(&*ys, [1, 2, 3]);
4135        }
4136    */
4137
4138    #[test]
4139    fn test_append() {
4140        let mut vec = thin_vec![1, 2, 3];
4141        let mut vec2 = thin_vec![4, 5, 6];
4142        vec.append(&mut vec2);
4143        assert_eq!(vec, [1, 2, 3, 4, 5, 6]);
4144        assert_eq!(vec2, []);
4145    }
4146
4147    #[test]
4148    fn test_split_off() {
4149        let mut vec = thin_vec![1, 2, 3, 4, 5, 6];
4150        let vec2 = vec.split_off(4);
4151        assert_eq!(vec, [1, 2, 3, 4]);
4152        assert_eq!(vec2, [5, 6]);
4153    }
4154
4155    #[test]
4156    fn test_into_iter_as_slice() {
4157        let vec = thin_vec!['a', 'b', 'c'];
4158        let mut into_iter = vec.into_iter();
4159        assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']);
4160        let _ = into_iter.next().unwrap();
4161        assert_eq!(into_iter.as_slice(), &['b', 'c']);
4162        let _ = into_iter.next().unwrap();
4163        let _ = into_iter.next().unwrap();
4164        assert_eq!(into_iter.as_slice(), &[]);
4165    }
4166
4167    #[test]
4168    fn test_into_iter_as_mut_slice() {
4169        let vec = thin_vec!['a', 'b', 'c'];
4170        let mut into_iter = vec.into_iter();
4171        assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']);
4172        into_iter.as_mut_slice()[0] = 'x';
4173        into_iter.as_mut_slice()[1] = 'y';
4174        assert_eq!(into_iter.next().unwrap(), 'x');
4175        assert_eq!(into_iter.as_slice(), &['y', 'c']);
4176    }
4177
4178    #[test]
4179    fn test_into_iter_debug() {
4180        let vec = thin_vec!['a', 'b', 'c'];
4181        let into_iter = vec.into_iter();
4182        let debug = format!("{:?}", into_iter);
4183        assert_eq!(debug, "IntoIter(['a', 'b', 'c'])");
4184    }
4185
4186    #[test]
4187    fn test_into_iter_count() {
4188        assert_eq!(thin_vec![1, 2, 3].into_iter().count(), 3);
4189    }
4190
4191    #[test]
4192    fn test_into_iter_clone() {
4193        fn iter_equal<I: Iterator<Item = i32>>(it: I, slice: &[i32]) {
4194            let v: ThinVec<i32> = it.collect();
4195            assert_eq!(&v[..], slice);
4196        }
4197        let mut it = thin_vec![1, 2, 3].into_iter();
4198        iter_equal(it.clone(), &[1, 2, 3]);
4199        assert_eq!(it.next(), Some(1));
4200        let mut it = it.rev();
4201        iter_equal(it.clone(), &[3, 2]);
4202        assert_eq!(it.next(), Some(3));
4203        iter_equal(it.clone(), &[2]);
4204        assert_eq!(it.next(), Some(2));
4205        iter_equal(it.clone(), &[]);
4206        assert_eq!(it.next(), None);
4207    }
4208
4209    #[allow(dead_code)]
4210    fn assert_covariance() {
4211        fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> {
4212            d
4213        }
4214        fn into_iter<'new>(i: IntoIter<&'static str>) -> IntoIter<&'new str> {
4215            i
4216        }
4217    }
4218
4219    /* TODO: specialize vec.into_iter().collect::<ThinVec<_>>();
4220        #[test]
4221        fn from_into_inner() {
4222            let vec = thin_vec![1, 2, 3];
4223            let ptr = vec.as_ptr();
4224            let vec = vec.into_iter().collect::<ThinVec<_>>();
4225            assert_eq!(vec, [1, 2, 3]);
4226            assert_eq!(vec.as_ptr(), ptr);
4227
4228            let ptr = &vec[1] as *const _;
4229            let mut it = vec.into_iter();
4230            it.next().unwrap();
4231            let vec = it.collect::<ThinVec<_>>();
4232            assert_eq!(vec, [2, 3]);
4233            assert!(ptr != vec.as_ptr());
4234        }
4235    */
4236
4237    #[test]
4238    #[cfg_attr(feature = "gecko-ffi", ignore)]
4239    fn overaligned_allocations() {
4240        #[repr(align(256))]
4241        struct Foo(usize);
4242        let mut v = thin_vec![Foo(273)];
4243        for i in 0..0x1000 {
4244            v.reserve_exact(i);
4245            assert!(v[0].0 == 273);
4246            assert!(v.as_ptr() as usize & 0xff == 0);
4247            v.shrink_to_fit();
4248            assert!(v[0].0 == 273);
4249            assert!(v.as_ptr() as usize & 0xff == 0);
4250        }
4251    }
4252
4253    /* TODO: implement drain_filter?
4254        #[test]
4255        fn drain_filter_empty() {
4256            let mut vec: ThinVec<i32> = thin_vec![];
4257
4258            {
4259                let mut iter = vec.drain_filter(|_| true);
4260                assert_eq!(iter.size_hint(), (0, Some(0)));
4261                assert_eq!(iter.next(), None);
4262                assert_eq!(iter.size_hint(), (0, Some(0)));
4263                assert_eq!(iter.next(), None);
4264                assert_eq!(iter.size_hint(), (0, Some(0)));
4265            }
4266            assert_eq!(vec.len(), 0);
4267            assert_eq!(vec, thin_vec![]);
4268        }
4269
4270        #[test]
4271        fn drain_filter_zst() {
4272            let mut vec = thin_vec![(), (), (), (), ()];
4273            let initial_len = vec.len();
4274            let mut count = 0;
4275            {
4276                let mut iter = vec.drain_filter(|_| true);
4277                assert_eq!(iter.size_hint(), (0, Some(initial_len)));
4278                while let Some(_) = iter.next() {
4279                    count += 1;
4280                    assert_eq!(iter.size_hint(), (0, Some(initial_len - count)));
4281                }
4282                assert_eq!(iter.size_hint(), (0, Some(0)));
4283                assert_eq!(iter.next(), None);
4284                assert_eq!(iter.size_hint(), (0, Some(0)));
4285            }
4286
4287            assert_eq!(count, initial_len);
4288            assert_eq!(vec.len(), 0);
4289            assert_eq!(vec, thin_vec![]);
4290        }
4291
4292        #[test]
4293        fn drain_filter_false() {
4294            let mut vec = thin_vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
4295
4296            let initial_len = vec.len();
4297            let mut count = 0;
4298            {
4299                let mut iter = vec.drain_filter(|_| false);
4300                assert_eq!(iter.size_hint(), (0, Some(initial_len)));
4301                for _ in iter.by_ref() {
4302                    count += 1;
4303                }
4304                assert_eq!(iter.size_hint(), (0, Some(0)));
4305                assert_eq!(iter.next(), None);
4306                assert_eq!(iter.size_hint(), (0, Some(0)));
4307            }
4308
4309            assert_eq!(count, 0);
4310            assert_eq!(vec.len(), initial_len);
4311            assert_eq!(vec, thin_vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
4312        }
4313
4314        #[test]
4315        fn drain_filter_true() {
4316            let mut vec = thin_vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
4317
4318            let initial_len = vec.len();
4319            let mut count = 0;
4320            {
4321                let mut iter = vec.drain_filter(|_| true);
4322                assert_eq!(iter.size_hint(), (0, Some(initial_len)));
4323                while let Some(_) = iter.next() {
4324                    count += 1;
4325                    assert_eq!(iter.size_hint(), (0, Some(initial_len - count)));
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, initial_len);
4333            assert_eq!(vec.len(), 0);
4334            assert_eq!(vec, thin_vec![]);
4335        }
4336
4337        #[test]
4338        fn drain_filter_complex() {
4339
4340            {   //                [+xxx++++++xxxxx++++x+x++]
4341                let mut vec = thin_vec![1,
4342                                   2, 4, 6,
4343                                   7, 9, 11, 13, 15, 17,
4344                                   18, 20, 22, 24, 26,
4345                                   27, 29, 31, 33,
4346                                   34,
4347                                   35,
4348                                   36,
4349                                   37, 39];
4350
4351                let removed = vec.drain_filter(|x| *x % 2 == 0).collect::<ThinVec<_>>();
4352                assert_eq!(removed.len(), 10);
4353                assert_eq!(removed, thin_vec![2, 4, 6, 18, 20, 22, 24, 26, 34, 36]);
4354
4355                assert_eq!(vec.len(), 14);
4356                assert_eq!(vec, thin_vec![1, 7, 9, 11, 13, 15, 17, 27, 29, 31, 33, 35, 37, 39]);
4357            }
4358
4359            {   //                [xxx++++++xxxxx++++x+x++]
4360                let mut vec = thin_vec![2, 4, 6,
4361                                   7, 9, 11, 13, 15, 17,
4362                                   18, 20, 22, 24, 26,
4363                                   27, 29, 31, 33,
4364                                   34,
4365                                   35,
4366                                   36,
4367                                   37, 39];
4368
4369                let removed = vec.drain_filter(|x| *x % 2 == 0).collect::<ThinVec<_>>();
4370                assert_eq!(removed.len(), 10);
4371                assert_eq!(removed, thin_vec![2, 4, 6, 18, 20, 22, 24, 26, 34, 36]);
4372
4373                assert_eq!(vec.len(), 13);
4374                assert_eq!(vec, thin_vec![7, 9, 11, 13, 15, 17, 27, 29, 31, 33, 35, 37, 39]);
4375            }
4376
4377            {   //                [xxx++++++xxxxx++++x+x]
4378                let mut vec = thin_vec![2, 4, 6,
4379                                   7, 9, 11, 13, 15, 17,
4380                                   18, 20, 22, 24, 26,
4381                                   27, 29, 31, 33,
4382                                   34,
4383                                   35,
4384                                   36];
4385
4386                let removed = vec.drain_filter(|x| *x % 2 == 0).collect::<ThinVec<_>>();
4387                assert_eq!(removed.len(), 10);
4388                assert_eq!(removed, thin_vec![2, 4, 6, 18, 20, 22, 24, 26, 34, 36]);
4389
4390                assert_eq!(vec.len(), 11);
4391                assert_eq!(vec, thin_vec![7, 9, 11, 13, 15, 17, 27, 29, 31, 33, 35]);
4392            }
4393
4394            {   //                [xxxxxxxxxx+++++++++++]
4395                let mut vec = thin_vec![2, 4, 6, 8, 10, 12, 14, 16, 18, 20,
4396                                   1, 3, 5, 7, 9, 11, 13, 15, 17, 19];
4397
4398                let removed = vec.drain_filter(|x| *x % 2 == 0).collect::<ThinVec<_>>();
4399                assert_eq!(removed.len(), 10);
4400                assert_eq!(removed, thin_vec![2, 4, 6, 8, 10, 12, 14, 16, 18, 20]);
4401
4402                assert_eq!(vec.len(), 10);
4403                assert_eq!(vec, thin_vec![1, 3, 5, 7, 9, 11, 13, 15, 17, 19]);
4404            }
4405
4406            {   //                [+++++++++++xxxxxxxxxx]
4407                let mut vec = thin_vec![1, 3, 5, 7, 9, 11, 13, 15, 17, 19,
4408                                   2, 4, 6, 8, 10, 12, 14, 16, 18, 20];
4409
4410                let removed = vec.drain_filter(|x| *x % 2 == 0).collect::<ThinVec<_>>();
4411                assert_eq!(removed.len(), 10);
4412                assert_eq!(removed, thin_vec![2, 4, 6, 8, 10, 12, 14, 16, 18, 20]);
4413
4414                assert_eq!(vec.len(), 10);
4415                assert_eq!(vec, thin_vec![1, 3, 5, 7, 9, 11, 13, 15, 17, 19]);
4416            }
4417        }
4418    */
4419    #[test]
4420    fn test_reserve_exact() {
4421        // This is all the same as test_reserve
4422
4423        let mut v = ThinVec::new();
4424        assert_eq!(v.capacity(), 0);
4425
4426        v.reserve_exact(2);
4427        assert!(v.capacity() >= 2);
4428
4429        for i in 0..16 {
4430            v.push(i);
4431        }
4432
4433        assert!(v.capacity() >= 16);
4434        v.reserve_exact(16);
4435        assert!(v.capacity() >= 32);
4436
4437        v.push(16);
4438
4439        v.reserve_exact(16);
4440        assert!(v.capacity() >= 33)
4441    }
4442
4443    /* TODO: implement try_reserve
4444        #[test]
4445        fn test_try_reserve() {
4446
4447            // These are the interesting cases:
4448            // * exactly isize::MAX should never trigger a CapacityOverflow (can be OOM)
4449            // * > isize::MAX should always fail
4450            //    * On 16/32-bit should CapacityOverflow
4451            //    * On 64-bit should OOM
4452            // * overflow may trigger when adding `len` to `cap` (in number of elements)
4453            // * overflow may trigger when multiplying `new_cap` by size_of::<T> (to get bytes)
4454
4455            const MAX_CAP: usize = isize::MAX as usize;
4456            const MAX_USIZE: usize = usize::MAX;
4457
4458            // On 16/32-bit, we check that allocations don't exceed isize::MAX,
4459            // on 64-bit, we assume the OS will give an OOM for such a ridiculous size.
4460            // Any platform that succeeds for these requests is technically broken with
4461            // ptr::offset because LLVM is the worst.
4462            let guards_against_isize = size_of::<usize>() < 8;
4463
4464            {
4465                // Note: basic stuff is checked by test_reserve
4466                let mut empty_bytes: ThinVec<u8> = ThinVec::new();
4467
4468                // Check isize::MAX doesn't count as an overflow
4469                if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_CAP) {
4470                    panic!("isize::MAX shouldn't trigger an overflow!");
4471                }
4472                // Play it again, frank! (just to be sure)
4473                if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_CAP) {
4474                    panic!("isize::MAX shouldn't trigger an overflow!");
4475                }
4476
4477                if guards_against_isize {
4478                    // Check isize::MAX + 1 does count as overflow
4479                    if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_CAP + 1) {
4480                    } else { panic!("isize::MAX + 1 should trigger an overflow!") }
4481
4482                    // Check usize::MAX does count as overflow
4483                    if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_USIZE) {
4484                    } else { panic!("usize::MAX should trigger an overflow!") }
4485                } else {
4486                    // Check isize::MAX + 1 is an OOM
4487                    if let Err(AllocErr) = empty_bytes.try_reserve(MAX_CAP + 1) {
4488                    } else { panic!("isize::MAX + 1 should trigger an OOM!") }
4489
4490                    // Check usize::MAX is an OOM
4491                    if let Err(AllocErr) = empty_bytes.try_reserve(MAX_USIZE) {
4492                    } else { panic!("usize::MAX should trigger an OOM!") }
4493                }
4494            }
4495
4496
4497            {
4498                // Same basic idea, but with non-zero len
4499                let mut ten_bytes: ThinVec<u8> = thin_vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
4500
4501                if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10) {
4502                    panic!("isize::MAX shouldn't trigger an overflow!");
4503                }
4504                if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10) {
4505                    panic!("isize::MAX shouldn't trigger an overflow!");
4506                }
4507                if guards_against_isize {
4508                    if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 9) {
4509                    } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
4510                } else {
4511                    if let Err(AllocErr) = ten_bytes.try_reserve(MAX_CAP - 9) {
4512                    } else { panic!("isize::MAX + 1 should trigger an OOM!") }
4513                }
4514                // Should always overflow in the add-to-len
4515                if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_USIZE) {
4516                } else { panic!("usize::MAX should trigger an overflow!") }
4517            }
4518
4519
4520            {
4521                // Same basic idea, but with interesting type size
4522                let mut ten_u32s: ThinVec<u32> = thin_vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
4523
4524                if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP/4 - 10) {
4525                    panic!("isize::MAX shouldn't trigger an overflow!");
4526                }
4527                if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP/4 - 10) {
4528                    panic!("isize::MAX shouldn't trigger an overflow!");
4529                }
4530                if guards_against_isize {
4531                    if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP/4 - 9) {
4532                    } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
4533                } else {
4534                    if let Err(AllocErr) = ten_u32s.try_reserve(MAX_CAP/4 - 9) {
4535                    } else { panic!("isize::MAX + 1 should trigger an OOM!") }
4536                }
4537                // Should fail in the mul-by-size
4538                if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_USIZE - 20) {
4539                } else {
4540                    panic!("usize::MAX should trigger an overflow!");
4541                }
4542            }
4543
4544        }
4545
4546        #[test]
4547        fn test_try_reserve_exact() {
4548
4549            // This is exactly the same as test_try_reserve with the method changed.
4550            // See that test for comments.
4551
4552            const MAX_CAP: usize = isize::MAX as usize;
4553            const MAX_USIZE: usize = usize::MAX;
4554
4555            let guards_against_isize = size_of::<usize>() < 8;
4556
4557            {
4558                let mut empty_bytes: ThinVec<u8> = ThinVec::new();
4559
4560                if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_CAP) {
4561                    panic!("isize::MAX shouldn't trigger an overflow!");
4562                }
4563                if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_CAP) {
4564                    panic!("isize::MAX shouldn't trigger an overflow!");
4565                }
4566
4567                if guards_against_isize {
4568                    if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_CAP + 1) {
4569                    } else { panic!("isize::MAX + 1 should trigger an overflow!") }
4570
4571                    if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_USIZE) {
4572                    } else { panic!("usize::MAX should trigger an overflow!") }
4573                } else {
4574                    if let Err(AllocErr) = empty_bytes.try_reserve_exact(MAX_CAP + 1) {
4575                    } else { panic!("isize::MAX + 1 should trigger an OOM!") }
4576
4577                    if let Err(AllocErr) = empty_bytes.try_reserve_exact(MAX_USIZE) {
4578                    } else { panic!("usize::MAX should trigger an OOM!") }
4579                }
4580            }
4581
4582
4583            {
4584                let mut ten_bytes: ThinVec<u8> = thin_vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
4585
4586                if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) {
4587                    panic!("isize::MAX shouldn't trigger an overflow!");
4588                }
4589                if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) {
4590                    panic!("isize::MAX shouldn't trigger an overflow!");
4591                }
4592                if guards_against_isize {
4593                    if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
4594                    } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
4595                } else {
4596                    if let Err(AllocErr) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
4597                    } else { panic!("isize::MAX + 1 should trigger an OOM!") }
4598                }
4599                if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_USIZE) {
4600                } else { panic!("usize::MAX should trigger an overflow!") }
4601            }
4602
4603
4604            {
4605                let mut ten_u32s: ThinVec<u32> = thin_vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
4606
4607                if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 10) {
4608                    panic!("isize::MAX shouldn't trigger an overflow!");
4609                }
4610                if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 10) {
4611                    panic!("isize::MAX shouldn't trigger an overflow!");
4612                }
4613                if guards_against_isize {
4614                    if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 9) {
4615                    } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
4616                } else {
4617                    if let Err(AllocErr) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 9) {
4618                    } else { panic!("isize::MAX + 1 should trigger an OOM!") }
4619                }
4620                if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_USIZE - 20) {
4621                } else { panic!("usize::MAX should trigger an overflow!") }
4622            }
4623        }
4624    */
4625
4626    #[cfg(feature = "gecko-ffi")]
4627    #[test]
4628    fn auto_t_array_basic() {
4629        crate::auto_thin_vec!(let t: [u8; 10]);
4630        assert_eq!(t.capacity(), 10);
4631        assert!(t.is_auto_array());
4632        assert!(t.uses_stack_allocated_buffer());
4633        assert!(!t.has_allocation());
4634        {
4635            let inner = unsafe { &mut *t.as_mut().as_mut_ptr() };
4636            for i in 0..30 {
4637                inner.push(i as u8);
4638            }
4639        }
4640
4641        assert!(t.is_auto_array());
4642        assert!(!t.uses_stack_allocated_buffer());
4643        assert_eq!(t.len(), 30);
4644        assert!(t.has_allocation());
4645        assert_eq!(t[5], 5);
4646        assert_eq!(t[29], 29);
4647        assert!(t.capacity() >= 30);
4648
4649        {
4650            let inner = unsafe { &mut *t.as_mut().as_mut_ptr() };
4651            inner.truncate(5);
4652        }
4653
4654        assert_eq!(t.len(), 5);
4655        assert!(t.capacity() >= 30);
4656        assert!(t.has_allocation());
4657        t.as_mut().shrink_to_fit();
4658        assert!(!t.has_allocation());
4659        assert!(t.is_auto_array());
4660        assert!(t.uses_stack_allocated_buffer());
4661        assert_eq!(t.capacity(), 10);
4662    }
4663
4664    #[test]
4665    #[cfg_attr(feature = "gecko-ffi", ignore)]
4666    fn test_header_data() {
4667        macro_rules! assert_aligned_head_ptr {
4668            ($typename:ty) => {{
4669                let v: ThinVec<$typename> = ThinVec::with_capacity(1 /* ensure allocation */);
4670                let head_ptr: *mut $typename = v.data_raw();
4671                assert_eq!(
4672                    head_ptr as usize % core::mem::align_of::<$typename>(),
4673                    0,
4674                    "expected Header::data<{}> to be aligned",
4675                    stringify!($typename)
4676                );
4677            }};
4678        }
4679
4680        const HEADER_SIZE: usize = core::mem::size_of::<Header>();
4681        assert_eq!(2 * core::mem::size_of::<usize>(), HEADER_SIZE);
4682
4683        #[repr(C, align(128))]
4684        struct Funky<T>(T);
4685        assert_eq!(padding::<Funky<()>>(), 128 - HEADER_SIZE);
4686        assert_aligned_head_ptr!(Funky<()>);
4687
4688        assert_eq!(padding::<Funky<u8>>(), 128 - HEADER_SIZE);
4689        assert_aligned_head_ptr!(Funky<u8>);
4690
4691        assert_eq!(padding::<Funky<[(); 1024]>>(), 128 - HEADER_SIZE);
4692        assert_aligned_head_ptr!(Funky<[(); 1024]>);
4693
4694        assert_eq!(padding::<Funky<[*mut usize; 1024]>>(), 128 - HEADER_SIZE);
4695        assert_aligned_head_ptr!(Funky<[*mut usize; 1024]>);
4696    }
4697
4698    #[cfg(feature = "serde")]
4699    use serde_test::{assert_tokens, Token};
4700
4701    #[test]
4702    #[cfg(feature = "serde")]
4703    fn test_ser_de_empty() {
4704        let vec = ThinVec::<u32>::new();
4705
4706        assert_tokens(&vec, &[Token::Seq { len: Some(0) }, Token::SeqEnd]);
4707    }
4708
4709    #[test]
4710    #[cfg(feature = "serde")]
4711    fn test_ser_de() {
4712        let mut vec = ThinVec::<u32>::new();
4713        vec.push(20);
4714        vec.push(55);
4715        vec.push(123);
4716
4717        assert_tokens(
4718            &vec,
4719            &[
4720                Token::Seq { len: Some(3) },
4721                Token::U32(20),
4722                Token::U32(55),
4723                Token::U32(123),
4724                Token::SeqEnd,
4725            ],
4726        );
4727    }
4728
4729    #[test]
4730    fn test_set_len() {
4731        let mut vec: ThinVec<u32> = thin_vec![];
4732        unsafe {
4733            vec.set_len(0); // at one point this caused a crash
4734        }
4735    }
4736
4737    #[test]
4738    #[should_panic(expected = "invalid set_len(1) on empty ThinVec")]
4739    fn test_set_len_invalid() {
4740        let mut vec: ThinVec<u32> = thin_vec![];
4741        unsafe {
4742            vec.set_len(1);
4743        }
4744    }
4745
4746    #[test]
4747    #[should_panic(expected = "capacity overflow")]
4748    fn test_capacity_overflow_header_too_big() {
4749        let vec: ThinVec<u8> = ThinVec::with_capacity(isize::MAX as usize - 2);
4750        assert!(vec.capacity() > 0);
4751    }
4752    #[test]
4753    #[should_panic(expected = "capacity overflow")]
4754    fn test_capacity_overflow_cap_too_big() {
4755        let vec: ThinVec<u8> = ThinVec::with_capacity(isize::MAX as usize + 1);
4756        assert!(vec.capacity() > 0);
4757    }
4758    #[test]
4759    #[should_panic(expected = "capacity overflow")]
4760    fn test_capacity_overflow_size_mul1() {
4761        let vec: ThinVec<u16> = ThinVec::with_capacity(isize::MAX as usize + 1);
4762        assert!(vec.capacity() > 0);
4763    }
4764    #[test]
4765    #[should_panic(expected = "capacity overflow")]
4766    fn test_capacity_overflow_size_mul2() {
4767        let vec: ThinVec<u16> = ThinVec::with_capacity(isize::MAX as usize / 2 + 1);
4768        assert!(vec.capacity() > 0);
4769    }
4770    #[test]
4771    #[should_panic(expected = "capacity overflow")]
4772    fn test_capacity_overflow_cap_really_isnt_isize() {
4773        let vec: ThinVec<u8> = ThinVec::with_capacity(isize::MAX as usize);
4774        assert!(vec.capacity() > 0);
4775    }
4776}