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