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