Skip to main content

thin_vec/
lib.rs

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