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