Skip to main content

qudit_core/utils/
limited.rs

1use std::alloc::{Layout, alloc, dealloc};
2use std::fmt;
3use std::hash::Hash;
4use std::ptr::NonNull;
5
6use serde::{Deserialize, Serialize};
7
8impl<T: Serialize> Serialize for LimitedSizeVec<T> {
9    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
10        use serde::ser::SerializeSeq;
11        let mut seq = serializer.serialize_seq(Some(self.len()))?;
12        for item in self.as_slice() {
13            seq.serialize_element(item)?;
14        }
15        seq.end()
16    }
17}
18
19impl<'de, T: Deserialize<'de>> Deserialize<'de> for LimitedSizeVec<T> {
20    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
21        struct Visitor<T>(std::marker::PhantomData<T>);
22
23        impl<'de, T: Deserialize<'de>> serde::de::Visitor<'de> for Visitor<T> {
24            type Value = LimitedSizeVec<T>;
25
26            fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
27                write!(f, "a sequence")
28            }
29
30            fn visit_seq<A: serde::de::SeqAccess<'de>>(
31                self,
32                mut seq: A,
33            ) -> Result<Self::Value, A::Error> {
34                let capacity = seq.size_hint().unwrap_or(DEFAULT_CAPACITY as usize);
35                let mut vec = LimitedSizeVec::new_with_capacity(capacity.max(1) as u32);
36                while let Some(item) = seq.next_element()? {
37                    vec.push(item);
38                }
39                Ok(vec)
40            }
41        }
42
43        deserializer.deserialize_seq(Visitor(std::marker::PhantomData))
44    }
45}
46
47/// A vector-like container with 32-bit length and capacity limits.
48///
49/// `LimitedSizeVec` is a performance-optimized vector implementation that uses
50/// `u32` for length and capacity instead of `usize`, limiting the maximum
51/// number of elements to 2³² - 1 (approximately 4.3 billion elements).
52/// This reduces memory overhead on 64-bit systems where the smaller size
53/// representation can improve cache performance.
54///
55/// # Memory Layout
56///
57/// The struct uses manual memory management with raw pointers for optimal
58/// performance. Memory is allocated using the global allocator and grows
59/// by doubling capacity when needed.
60///
61/// # Safety
62///
63/// This implementation maintains memory safety through careful pointer
64/// arithmetic and proper Drop implementation. All unsafe operations are
65/// encapsulated within safe public methods.
66///
67/// # Limits
68///
69/// - Maximum capacity: `u32::MAX` (4,294,967,295 elements)
70/// - Initial capacity: 8 elements (when using `new()`)
71/// - Growth factor: 2x when capacity is exceeded
72///
73/// # Examples
74///
75/// ```rust
76/// # use qudit_core::LimitedSizeVec;
77///
78/// // Create a new vector
79/// let mut vec = LimitedSizeVec::new();
80/// assert_eq!(vec.len(), 0);
81/// assert_eq!(vec.capacity(), 8);
82///
83/// // Add elements
84/// vec.push("hello");
85/// vec.push("world");
86/// assert_eq!(vec.len(), 2);
87///
88/// // Access elements
89/// assert_eq!(vec[0], "hello");
90/// assert_eq!(vec.get(1), Some(&"world"));
91///
92/// // Convert to slice
93/// let slice: &[&str] = vec.as_slice();
94/// assert_eq!(slice, ["hello", "world"]);
95/// ```
96#[repr(C)]
97pub struct LimitedSizeVec<T> {
98    data: NonNull<T>,
99    len: u32,
100    capacity: u32,
101}
102
103/// Default initial capacity for new vectors
104const DEFAULT_CAPACITY: u32 = 8;
105
106impl<T> LimitedSizeVec<T> {
107    /// Creates a new empty vector with default capacity.
108    ///
109    /// The vector will initially allocate space for 8 elements.
110    ///
111    /// # Examples
112    ///
113    /// ```rust
114    /// use qudit_core::LimitedSizeVec;
115    ///
116    /// let vec: LimitedSizeVec<i32> = LimitedSizeVec::new();
117    /// assert_eq!(vec.len(), 0);
118    /// assert_eq!(vec.capacity(), 8);
119    /// ```
120    #[inline]
121    pub fn new() -> Self {
122        Self::new_with_capacity(DEFAULT_CAPACITY)
123    }
124
125    /// Creates a new empty vector with the specified capacity.
126    ///
127    /// # Arguments
128    /// * `capacity` - The initial capacity (must be > 0)
129    ///
130    /// # Panics
131    /// Panics if capacity is 0 or if memory allocation fails.
132    ///
133    /// # Examples
134    ///
135    /// ```rust
136    /// use qudit_core::LimitedSizeVec;
137    ///
138    /// let vec: LimitedSizeVec<i32> = LimitedSizeVec::new_with_capacity(100);
139    /// assert_eq!(vec.len(), 0);
140    /// assert_eq!(vec.capacity(), 100);
141    /// ```
142    #[inline]
143    pub fn new_with_capacity(capacity: u32) -> Self {
144        if capacity == 0 {
145            Self::zero_capacity_panic();
146        }
147
148        let layout =
149            Layout::array::<T>(capacity as usize).unwrap_or_else(|_| Self::layout_error_panic());
150
151        let ptr = unsafe { alloc(layout) as *mut T };
152        let non_null = NonNull::new(ptr).unwrap_or_else(|| Self::allocation_failed_panic());
153
154        Self {
155            data: non_null,
156            len: 0,
157            capacity,
158        }
159    }
160
161    #[cold]
162    #[inline(never)]
163    fn zero_capacity_panic() -> ! {
164        panic!("Cannot create vector with zero capacity");
165    }
166
167    #[cold]
168    #[inline(never)]
169    fn layout_error_panic() -> ! {
170        panic!("Failed to create memory layout for vector");
171    }
172
173    #[cold]
174    #[inline(never)]
175    fn allocation_failed_panic() -> ! {
176        panic!("Memory allocation failed");
177    }
178
179    /// Appends an element to the back of the vector.
180    ///
181    /// If the vector's capacity is exceeded, it will be reallocated with
182    /// double the previous capacity.
183    ///
184    /// # Arguments
185    /// * `value` - The element to append
186    ///
187    /// # Examples
188    ///
189    /// ```rust
190    /// # use qudit_core::LimitedSizeVec;
191    ///
192    /// let mut vec = LimitedSizeVec::new();
193    /// vec.push(42);
194    /// vec.push(100);
195    /// assert_eq!(vec.len(), 2);
196    /// assert_eq!(vec[0], 42);
197    /// assert_eq!(vec[1], 100);
198    /// ```
199    #[inline]
200    pub fn push(&mut self, value: T) {
201        if self.len >= self.capacity {
202            self.grow();
203        }
204        unsafe {
205            self.data.as_ptr().add(self.len as usize).write(value);
206        }
207        self.len += 1;
208    }
209
210    /// Grows the vector's capacity.
211    ///
212    /// Doubles the current capacity, with a minimum of 8 elements.
213    /// This method is called automatically when needed by `push()`.
214    fn grow(&mut self) {
215        let new_capacity = if self.capacity == 0 {
216            DEFAULT_CAPACITY
217        } else {
218            self.capacity.saturating_mul(2)
219        };
220
221        unsafe {
222            let new_layout = Layout::array::<T>(new_capacity as usize).unwrap();
223            let new_ptr = alloc(new_layout) as *mut T;
224
225            if new_ptr.is_null() {
226                Self::allocation_failed_panic();
227            }
228
229            // Zero capacity only possible with dangling pointer; special case
230            if self.capacity != 0 {
231                let old_ptr = self.data.as_ptr();
232                std::ptr::copy_nonoverlapping(old_ptr, new_ptr, self.len as usize);
233                let old_layout = Layout::array::<T>(self.capacity as usize).unwrap();
234                dealloc(old_ptr as *mut u8, old_layout);
235            }
236
237            self.data = NonNull::new(new_ptr).unwrap();
238        }
239        self.capacity = new_capacity;
240    }
241
242    /// Grows the vector's capacity to at least the specified capacity.
243    fn grow_to_capacity(&mut self, new_capacity: u32) {
244        if new_capacity <= self.capacity {
245            return;
246        }
247
248        unsafe {
249            let new_layout = Layout::array::<T>(new_capacity as usize).unwrap();
250            let new_ptr = alloc(new_layout) as *mut T;
251
252            if new_ptr.is_null() {
253                Self::allocation_failed_panic();
254            }
255
256            // Copy existing elements if any
257            if self.capacity != 0 {
258                let old_ptr = self.data.as_ptr();
259                std::ptr::copy_nonoverlapping(old_ptr, new_ptr, self.len as usize);
260                let old_layout = Layout::array::<T>(self.capacity as usize).unwrap();
261                dealloc(old_ptr as *mut u8, old_layout);
262            }
263
264            self.data = NonNull::new(new_ptr).unwrap();
265        }
266        self.capacity = new_capacity;
267    }
268
269    /// Returns the number of elements in the vector.
270    ///
271    /// # Examples
272    ///
273    /// ```rust
274    /// # use qudit_core::LimitedSizeVec;
275    ///
276    /// let mut vec = LimitedSizeVec::new();
277    /// assert_eq!(vec.len(), 0);
278    ///
279    /// vec.push("hello");
280    /// assert_eq!(vec.len(), 1);
281    /// ```
282    #[inline(always)]
283    pub fn len(&self) -> usize {
284        self.len as usize
285    }
286
287    /// Returns the total capacity of the vector.
288    ///
289    /// # Examples
290    ///
291    /// ```rust
292    /// # use qudit_core::LimitedSizeVec;
293    ///
294    /// let vec: LimitedSizeVec<i32> = LimitedSizeVec::new_with_capacity(50);
295    /// assert_eq!(vec.capacity(), 50);
296    /// ```
297    #[inline(always)]
298    pub fn capacity(&self) -> usize {
299        self.capacity as usize
300    }
301
302    /// Returns `true` if the vector contains no elements.
303    ///
304    /// # Examples
305    ///
306    /// ```rust
307    /// # use qudit_core::LimitedSizeVec;
308    ///
309    /// let mut vec = LimitedSizeVec::new();
310    /// assert!(vec.is_empty());
311    ///
312    /// vec.push(42);
313    /// assert!(!vec.is_empty());
314    /// ```
315    #[inline(always)]
316    pub const fn is_empty(&self) -> bool {
317        self.len == 0
318    }
319
320    /// Returns a reference to the element at the given index, or `None` if out of bounds.
321    ///
322    /// # Arguments
323    /// * `index` - The index to access
324    ///
325    /// # Examples
326    ///
327    /// ```rust
328    /// # use qudit_core::LimitedSizeVec;
329    ///
330    /// let mut vec = LimitedSizeVec::new();
331    /// vec.push("hello");
332    ///
333    /// assert_eq!(vec.get(0), Some(&"hello"));
334    /// assert_eq!(vec.get(1), None);
335    /// ```
336    #[inline]
337    pub fn get(&self, index: usize) -> Option<&T> {
338        if index < self.len as usize {
339            unsafe { Some(&*self.data.as_ptr().add(index)) }
340        } else {
341            None
342        }
343    }
344
345    /// Returns a mutable reference to the element at the given index, or `None` if out of bounds.
346    ///
347    /// # Arguments
348    /// * `index` - The index to access
349    ///
350    /// # Examples
351    ///
352    /// ```rust
353    /// # use qudit_core::LimitedSizeVec;
354    ///
355    /// let mut vec = LimitedSizeVec::new();
356    /// vec.push(String::from("hello"));
357    ///
358    /// if let Some(element) = vec.get_mut(0) {
359    ///     element.push_str(" world");
360    /// }
361    /// assert_eq!(vec[0], "hello world");
362    /// ```
363    #[inline]
364    pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
365        if index < self.len as usize {
366            unsafe { Some(&mut *self.data.as_ptr().add(index)) }
367        } else {
368            None
369        }
370    }
371
372    /// Returns a reference to an element without bounds checking.
373    ///
374    /// # Safety
375    /// Calling this method with an out-of-bounds index is undefined behavior.
376    /// The caller must ensure that `index < self.len()`.
377    ///
378    /// # Arguments
379    /// * `index` - The index to access
380    ///
381    /// # Examples
382    ///
383    /// ```rust
384    /// # use qudit_core::LimitedSizeVec;
385    ///
386    /// let mut vec = LimitedSizeVec::new();
387    /// vec.push("hello");
388    ///
389    /// unsafe {
390    ///     assert_eq!(vec.get_unchecked(0), &"hello");
391    /// }
392    /// ```
393    #[inline]
394    pub unsafe fn get_unchecked(&self, index: usize) -> &T {
395        unsafe {
396            debug_assert!(
397                index < self.len as usize,
398                "index out of bounds: {} >= {}",
399                index,
400                self.len
401            );
402            &*self.data.as_ptr().add(index)
403        }
404    }
405
406    /// Returns a mutable reference to an element without bounds checking.
407    ///
408    /// # Safety
409    /// Calling this method with an out-of-bounds index is undefined behavior.
410    /// The caller must ensure that `index < self.len()`.
411    ///
412    /// # Arguments
413    /// * `index` - The index to access
414    ///
415    /// # Examples
416    ///
417    /// ```rust
418    /// # use qudit_core::LimitedSizeVec;
419    ///
420    /// let mut vec = LimitedSizeVec::new();
421    /// vec.push(String::from("hello"));
422    ///
423    /// unsafe {
424    ///     vec.get_mut_unchecked(0).push_str(" world");
425    /// }
426    /// assert_eq!(vec[0], "hello world");
427    /// ```
428    #[inline]
429    pub unsafe fn get_mut_unchecked(&mut self, index: usize) -> &mut T {
430        unsafe {
431            debug_assert!(
432                index < self.len as usize,
433                "index out of bounds: {} >= {}",
434                index,
435                self.len
436            );
437            &mut *self.data.as_ptr().add(index)
438        }
439    }
440
441    /// Removes the last element from the vector and returns it, or `None` if empty.
442    ///
443    /// # Examples
444    ///
445    /// ```rust
446    /// # use qudit_core::LimitedSizeVec;
447    ///
448    /// let mut vec = LimitedSizeVec::new();
449    /// vec.push(1);
450    /// vec.push(2);
451    ///
452    /// assert_eq!(vec.pop(), Some(2));
453    /// assert_eq!(vec.pop(), Some(1));
454    /// assert_eq!(vec.pop(), None);
455    /// ```
456    #[inline]
457    pub fn pop(&mut self) -> Option<T> {
458        if self.len > 0 {
459            self.len -= 1;
460            unsafe { Some(std::ptr::read(self.data.as_ptr().add(self.len as usize))) }
461        } else {
462            None
463        }
464    }
465
466    /// Removes and returns the element at position `index`, shifting all elements after it to the left.
467    ///
468    /// # Panics
469    /// Panics if `index` is out of bounds.
470    ///
471    /// # Examples
472    ///
473    /// ```rust
474    /// # use qudit_core::LimitedSizeVec;
475    ///
476    /// let mut vec = LimitedSizeVec::new();
477    /// vec.push("a");
478    /// vec.push("b");
479    /// vec.push("c");
480    ///
481    /// assert_eq!(vec.remove(1), "b");
482    /// assert_eq!(vec.as_slice(), ["a", "c"]);
483    /// ```
484    #[inline]
485    pub fn remove(&mut self, index: usize) -> T {
486        if index >= self.len as usize {
487            panic!(
488                "removal index (is {}) should be < len (is {})",
489                index, self.len
490            );
491        }
492
493        unsafe {
494            let ptr = self.data.as_ptr().add(index);
495            let ret = std::ptr::read(ptr);
496
497            // Shift elements left
498            let remaining = self.len as usize - index - 1;
499            if remaining > 0 {
500                std::ptr::copy(ptr.add(1), ptr, remaining);
501            }
502
503            self.len -= 1;
504            ret
505        }
506    }
507
508    /// Inserts an element at position `index`, shifting all elements after it to the right.
509    ///
510    /// # Panics
511    /// Panics if `index > len`.
512    ///
513    /// # Examples
514    ///
515    /// ```rust
516    /// # use qudit_core::LimitedSizeVec;
517    ///
518    /// let mut vec = LimitedSizeVec::new();
519    /// vec.push("a");
520    /// vec.push("c");
521    ///
522    /// vec.insert(1, "b");
523    /// assert_eq!(vec.as_slice(), ["a", "b", "c"]);
524    /// ```
525    #[inline]
526    pub fn insert(&mut self, index: usize, element: T) {
527        if index > self.len as usize {
528            panic!(
529                "insertion index (is {}) should be <= len (is {})",
530                index, self.len
531            );
532        }
533
534        if self.len >= self.capacity {
535            self.grow();
536        }
537
538        unsafe {
539            let ptr = self.data.as_ptr().add(index);
540
541            // Shift elements right
542            let remaining = self.len as usize - index;
543            if remaining > 0 {
544                std::ptr::copy(ptr, ptr.add(1), remaining);
545            }
546
547            std::ptr::write(ptr, element);
548            self.len += 1;
549        }
550    }
551
552    /// Shortens the vector, keeping the first `len` elements and dropping the rest.
553    ///
554    /// If `len` is greater than the vector's current length, this has no effect.
555    ///
556    /// # Examples
557    ///
558    /// ```rust
559    /// # use qudit_core::LimitedSizeVec;
560    ///
561    /// let mut vec = LimitedSizeVec::new();
562    /// vec.push(1);
563    /// vec.push(2);
564    /// vec.push(3);
565    /// vec.push(4);
566    ///
567    /// vec.truncate(2);
568    /// assert_eq!(vec.as_slice(), [1, 2]);
569    /// ```
570    #[inline]
571    pub fn truncate(&mut self, len: usize) {
572        if len < self.len as usize {
573            let new_len = len as u32;
574            if std::mem::needs_drop::<T>() {
575                unsafe {
576                    for i in new_len..self.len {
577                        std::ptr::drop_in_place(self.data.as_ptr().add(i as usize));
578                    }
579                }
580            }
581            self.len = new_len;
582        }
583    }
584
585    /// Resizes the vector to the given length.
586    ///
587    /// If `new_len` is greater than `len`, the vector is extended with clones of `value`.
588    /// If `new_len` is less than `len`, the vector is truncated.
589    ///
590    /// # Examples
591    ///
592    /// ```rust
593    /// # use qudit_core::LimitedSizeVec;
594    ///
595    /// let mut vec = LimitedSizeVec::new();
596    /// vec.push(1);
597    ///
598    /// vec.resize(3, 0);
599    /// assert_eq!(vec.as_slice(), [1, 0, 0]);
600    ///
601    /// vec.resize(1, 2);
602    /// assert_eq!(vec.as_slice(), [1]);
603    /// ```
604    #[inline]
605    pub fn resize(&mut self, new_len: usize, value: T)
606    where
607        T: Clone,
608    {
609        let current_len = self.len as usize;
610        if new_len > current_len {
611            self.reserve(new_len - current_len);
612            for _ in current_len..new_len {
613                self.push(value.clone());
614            }
615        } else {
616            self.truncate(new_len);
617        }
618    }
619
620    /// Extends the vector by cloning elements from a slice.
621    ///
622    /// # Examples
623    ///
624    /// ```rust
625    /// # use qudit_core::LimitedSizeVec;
626    ///
627    /// let mut vec = LimitedSizeVec::new();
628    /// vec.push(1);
629    ///
630    /// vec.extend_from_slice(&[2, 3, 4]);
631    /// assert_eq!(vec.as_slice(), [1, 2, 3, 4]);
632    /// ```
633    #[inline]
634    pub fn extend_from_slice(&mut self, other: &[T])
635    where
636        T: Clone,
637    {
638        self.reserve(other.len());
639        for item in other {
640            self.push(item.clone());
641        }
642    }
643
644    /// Reserves capacity for at least `additional` more elements.
645    ///
646    /// Does nothing if the capacity is already sufficient.
647    ///
648    /// # Examples
649    ///
650    /// ```rust
651    /// # use qudit_core::LimitedSizeVec;
652    ///
653    /// let mut vec: LimitedSizeVec<usize> = LimitedSizeVec::new();
654    /// vec.reserve(100);
655    /// assert!(vec.capacity() >= 100);
656    /// ```
657    #[inline]
658    pub fn reserve(&mut self, additional: usize) {
659        let required = self.len as usize + additional;
660        if required > self.capacity as usize {
661            self.grow_to_capacity(required.max(self.capacity as usize * 2) as u32);
662        }
663    }
664
665    /// Appends an element without checking capacity.
666    ///
667    /// # Safety
668    /// The caller must ensure that `self.len < self.capacity`.
669    ///
670    /// # Examples
671    ///
672    /// ```rust
673    /// # use qudit_core::LimitedSizeVec;
674    ///
675    /// let mut vec = LimitedSizeVec::new_with_capacity(10);
676    /// unsafe {
677    ///     vec.push_unchecked(42);
678    /// }
679    /// assert_eq!(vec[0], 42);
680    /// ```
681    #[inline]
682    pub unsafe fn push_unchecked(&mut self, value: T) {
683        unsafe {
684            debug_assert!(
685                self.len < self.capacity,
686                "capacity exceeded: {} >= {}",
687                self.len,
688                self.capacity
689            );
690            self.data.as_ptr().add(self.len as usize).write(value);
691            self.len += 1;
692        }
693    }
694
695    /// Clears the vector, removing all elements but keeping allocated capacity.
696    ///
697    /// # Examples
698    ///
699    /// ```rust
700    /// # use qudit_core::LimitedSizeVec;
701    ///
702    /// let mut vec = LimitedSizeVec::new();
703    /// vec.push(1);
704    /// vec.push(2);
705    ///
706    /// let old_capacity = vec.capacity();
707    /// vec.clear();
708    ///
709    /// assert_eq!(vec.len(), 0);
710    /// assert_eq!(vec.capacity(), old_capacity);
711    /// ```
712    #[inline]
713    pub fn clear(&mut self) {
714        if self.len > 0 {
715            if std::mem::needs_drop::<T>() {
716                for i in 0..self.len {
717                    unsafe {
718                        std::ptr::drop_in_place(self.data.as_ptr().add(i as usize));
719                    }
720                }
721            }
722            self.len = 0;
723        }
724    }
725
726    /// Sorts the vector in-place using the natural ordering of elements.
727    ///
728    /// This method requires that `T` implements `Ord`.
729    ///
730    /// # Examples
731    ///
732    /// ```rust
733    /// # use qudit_core::LimitedSizeVec;
734    ///
735    /// let mut vec = LimitedSizeVec::new();
736    /// vec.push(3);
737    /// vec.push(1);
738    /// vec.push(2);
739    ///
740    /// vec.sort();
741    /// assert_eq!(vec.as_slice(), [1, 2, 3]);
742    /// ```
743    #[inline]
744    pub fn sort(&mut self)
745    where
746        T: Ord,
747    {
748        let slice = self.as_slice_mut();
749        slice.sort();
750    }
751
752    /// Takes ownership of the vector's contents, leaving the original empty.
753    ///
754    /// This is a zero-cost operation that transfers ownership without cloning.
755    ///
756    /// # Examples
757    ///
758    /// ```rust
759    /// # use qudit_core::LimitedSizeVec;
760    ///
761    /// let mut vec1 = LimitedSizeVec::new();
762    /// vec1.push(1);
763    /// vec1.push(2);
764    ///
765    /// let vec2 = vec1.take();
766    /// assert_eq!(vec1.len(), 0);
767    /// assert_eq!(vec2.len(), 2);
768    /// ```
769    #[inline]
770    pub fn take(&mut self) -> Self {
771        let cap = self.capacity;
772        let len = self.len;
773        let ptr = self.data;
774
775        // Reset self to valid empty state
776        self.data = NonNull::dangling();
777        self.len = 0;
778        self.capacity = 0;
779
780        Self {
781            data: ptr,
782            len,
783            capacity: cap,
784        }
785    }
786
787    /// Creates a new vector by cloning this one.
788    ///
789    /// This method is equivalent to `clone()` but provides a more explicit name.
790    ///
791    /// # Examples
792    ///
793    /// ```rust
794    /// # use qudit_core::LimitedSizeVec;
795    ///
796    /// let mut vec1 = LimitedSizeVec::new();
797    /// vec1.push("hello".to_string());
798    ///
799    /// let vec2 = vec1.to_owned();
800    /// assert_eq!(vec1.len(), 1);
801    /// assert_eq!(vec2.len(), 1);
802    /// ```
803    #[inline]
804    pub fn to_owned(&self) -> Self
805    where
806        T: Clone,
807    {
808        self.clone()
809    }
810
811    /// Returns the vector's contents as a slice.
812    ///
813    /// # Examples
814    ///
815    /// ```rust
816    /// # use qudit_core::LimitedSizeVec;
817    ///
818    /// let mut vec = LimitedSizeVec::new();
819    /// vec.push(1);
820    /// vec.push(2);
821    ///
822    /// let slice = vec.as_slice();
823    /// assert_eq!(slice, [1, 2]);
824    /// ```
825    #[inline(always)]
826    pub fn as_slice(&self) -> &[T] {
827        unsafe { std::slice::from_raw_parts(self.data.as_ptr(), self.len as usize) }
828    }
829
830    /// Returns the vector's contents as a mutable slice.
831    ///
832    /// # Examples
833    ///
834    /// ```rust
835    /// # use qudit_core::LimitedSizeVec;
836    ///
837    /// let mut vec = LimitedSizeVec::new();
838    /// vec.push(1);
839    /// vec.push(2);
840    ///
841    /// let slice = vec.as_slice_mut();
842    /// slice[0] = 10;
843    /// assert_eq!(vec[0], 10);
844    /// ```
845    #[inline(always)]
846    pub fn as_slice_mut(&mut self) -> &mut [T] {
847        unsafe { std::slice::from_raw_parts_mut(self.data.as_ptr(), self.len as usize) }
848    }
849}
850
851impl<T: Clone> Clone for LimitedSizeVec<T> {
852    /// Creates a clone of the vector.
853    ///
854    /// All elements are cloned individually, and the new vector will have
855    /// the same capacity as the original.
856    ///
857    /// # Examples
858    ///
859    /// ```rust
860    /// # use qudit_core::LimitedSizeVec;
861    ///
862    /// let mut vec1 = LimitedSizeVec::new();
863    /// vec1.push("hello".to_string());
864    ///
865    /// let vec2 = vec1.clone();
866    /// assert_eq!(vec1.len(), vec2.len());
867    /// assert_eq!(vec1[0], vec2[0]);
868    /// ```
869    fn clone(&self) -> Self {
870        if self.len == 0 {
871            return Self::new_with_capacity(self.capacity);
872        }
873
874        let mut new_vec = Self::new_with_capacity(self.capacity);
875
876        // Clone each element individually for safety
877        for i in 0..self.len {
878            unsafe {
879                let item = &*self.data.as_ptr().add(i as usize);
880                new_vec.push(item.clone());
881            }
882        }
883
884        new_vec
885    }
886}
887
888impl<T> Default for LimitedSizeVec<T> {
889    /// Creates an empty vector with default capacity.
890    #[inline]
891    fn default() -> Self {
892        Self::new()
893    }
894}
895
896impl<T: fmt::Debug> fmt::Debug for LimitedSizeVec<T> {
897    /// Formats the vector for debugging output.
898    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
899        f.debug_list().entries(self.as_slice().iter()).finish()
900    }
901}
902
903impl<T: PartialEq> PartialEq for LimitedSizeVec<T> {
904    fn eq(&self, other: &Self) -> bool {
905        if self.len != other.len {
906            return false;
907        }
908        self.as_slice().eq(other.as_slice())
909    }
910}
911
912impl<T: Eq> Eq for LimitedSizeVec<T> {}
913
914impl<T: Hash> Hash for LimitedSizeVec<T> {
915    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
916        self.len.hash(state);
917        self.as_slice().hash(state);
918    }
919}
920
921impl<T> std::ops::Deref for LimitedSizeVec<T> {
922    type Target = [T];
923
924    #[inline(always)]
925    fn deref(&self) -> &Self::Target {
926        self.as_slice()
927    }
928}
929
930impl<T> std::ops::DerefMut for LimitedSizeVec<T> {
931    #[inline(always)]
932    fn deref_mut(&mut self) -> &mut Self::Target {
933        self.as_slice_mut()
934    }
935}
936
937impl<T> std::ops::Index<usize> for LimitedSizeVec<T> {
938    type Output = T;
939
940    #[inline(always)]
941    fn index(&self, index: usize) -> &Self::Output {
942        &self.as_slice()[index]
943    }
944}
945
946impl<T> std::ops::IndexMut<usize> for LimitedSizeVec<T> {
947    #[inline(always)]
948    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
949        &mut self.as_slice_mut()[index]
950    }
951}
952
953impl<T> AsRef<[T]> for LimitedSizeVec<T> {
954    #[inline(always)]
955    fn as_ref(&self) -> &[T] {
956        self.as_slice()
957    }
958}
959
960impl<T> AsMut<[T]> for LimitedSizeVec<T> {
961    #[inline(always)]
962    fn as_mut(&mut self) -> &mut [T] {
963        self.as_slice_mut()
964    }
965}
966
967impl<T> From<Vec<T>> for LimitedSizeVec<T> {
968    /// Converts a `Vec<T>` into a `LimitedSizeVec<T>`.
969    ///
970    fn from(vec: Vec<T>) -> Self {
971        let len = vec.len();
972        let capacity = vec.capacity();
973
974        if capacity > u32::MAX as usize {
975            panic!("Vector capacity exceeds maximum allowed for LimitedSizeVec (u32::MAX)");
976        }
977
978        // Prevent `vec` from dropping its contents
979        let mut temp_vec = std::mem::ManuallyDrop::new(vec);
980
981        // Get raw parts
982        let ptr = temp_vec.as_mut_ptr();
983        let len_u32 = len as u32; // Assuming len fits, as capacity is checked
984        let cap_u32 = capacity as u32;
985
986        LimitedSizeVec {
987            data: NonNull::new(ptr).unwrap_or_else(|| Self::allocation_failed_panic()),
988            len: len_u32,
989            capacity: cap_u32,
990        }
991    }
992}
993
994impl<T: Clone> From<&[T]> for LimitedSizeVec<T> {
995    /// Converts a slice into a `LimitedSizeVec<T>` by cloning elements.
996    fn from(slice: &[T]) -> Self {
997        let mut limited_vec =
998            Self::new_with_capacity(slice.len().max(DEFAULT_CAPACITY as usize) as u32);
999        for item in slice {
1000            limited_vec.push(item.clone());
1001        }
1002        limited_vec
1003    }
1004}
1005
1006impl<T: Clone> From<&Vec<T>> for LimitedSizeVec<T> {
1007    /// Converts a `&Vec<T>` into a `LimitedSizeVec<T>` by cloning elements.
1008    #[inline]
1009    fn from(vec: &Vec<T>) -> Self {
1010        Self::from(vec.as_slice())
1011    }
1012}
1013
1014impl<T> FromIterator<T> for LimitedSizeVec<T> {
1015    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
1016        let iter = iter.into_iter();
1017        let (lower_bound, _) = iter.size_hint();
1018        let mut vec =
1019            LimitedSizeVec::new_with_capacity(lower_bound.max(DEFAULT_CAPACITY as usize) as u32);
1020        for item in iter {
1021            vec.push(item);
1022        }
1023        vec
1024    }
1025}
1026
1027impl<T> From<LimitedSizeVec<T>> for Vec<T> {
1028    /// Converts a `LimitedSizeVec<T>` into a `Vec<T>` without copying elements.
1029    ///
1030    /// This is a zero-cost conversion that transfers ownership of the underlying buffer.
1031    fn from(mut limited_vec: LimitedSizeVec<T>) -> Self {
1032        let len = limited_vec.len();
1033        let capacity = limited_vec.capacity();
1034        let ptr = limited_vec.data.as_ptr();
1035
1036        // Prevent limited_vec from dropping the memory by resetting it
1037        limited_vec.data = NonNull::dangling();
1038        limited_vec.len = 0;
1039        limited_vec.capacity = 0;
1040
1041        unsafe { Self::from_raw_parts(ptr, len, capacity) }
1042    }
1043}
1044
1045/// An iterator that moves out of a `LimitedSizeVec`.
1046pub struct IntoIter<T> {
1047    data: NonNull<T>,
1048    start: *const T,
1049    end: *const T,
1050    capacity: u32,
1051}
1052
1053impl<T> Iterator for IntoIter<T> {
1054    type Item = T;
1055
1056    #[inline]
1057    fn next(&mut self) -> Option<Self::Item> {
1058        if self.start == self.end {
1059            None
1060        } else {
1061            unsafe {
1062                let current = self.start;
1063                self.start = self.start.add(1);
1064                Some(std::ptr::read(current))
1065            }
1066        }
1067    }
1068
1069    #[inline]
1070    fn size_hint(&self) -> (usize, Option<usize>) {
1071        let len = unsafe { self.end.offset_from(self.start) } as usize;
1072        (len, Some(len))
1073    }
1074}
1075
1076impl<T> DoubleEndedIterator for IntoIter<T> {
1077    #[inline]
1078    fn next_back(&mut self) -> Option<Self::Item> {
1079        if self.start == self.end {
1080            None
1081        } else {
1082            unsafe {
1083                self.end = self.end.sub(1);
1084                Some(std::ptr::read(self.end))
1085            }
1086        }
1087    }
1088}
1089
1090impl<T> ExactSizeIterator for IntoIter<T> {}
1091
1092impl<T> Drop for IntoIter<T> {
1093    fn drop(&mut self) {
1094        // Drop any remaining elements
1095        for _ in &mut *self {}
1096
1097        // Deallocate memory if we have capacity
1098        if self.capacity > 0 {
1099            unsafe {
1100                dealloc(
1101                    self.data.as_ptr() as *mut u8,
1102                    Layout::array::<T>(self.capacity as usize).unwrap(),
1103                );
1104            }
1105        }
1106    }
1107}
1108
1109impl<T> IntoIterator for LimitedSizeVec<T> {
1110    type Item = T;
1111    type IntoIter = IntoIter<T>;
1112
1113    /// Creates a consuming iterator, that is, one that moves each value out of
1114    /// the vector (from start to end). The vector cannot be used after calling this.
1115    ///
1116    /// # Examples
1117    ///
1118    /// ```rust
1119    /// # use qudit_core::LimitedSizeVec;
1120    ///
1121    /// let mut vec = LimitedSizeVec::new();
1122    /// vec.push(1);
1123    /// vec.push(2);
1124    /// vec.push(3);
1125    ///
1126    /// let mut iterator = vec.into_iter();
1127    /// assert_eq!(iterator.next(), Some(1));
1128    /// assert_eq!(iterator.next(), Some(2));
1129    /// assert_eq!(iterator.next(), Some(3));
1130    /// assert_eq!(iterator.next(), None);
1131    /// ```
1132    #[inline]
1133    fn into_iter(mut self) -> Self::IntoIter {
1134        let ptr = self.data.as_ptr();
1135        let len = self.len as usize;
1136        let capacity = self.capacity;
1137
1138        // Prevent the vector from being dropped
1139        self.data = NonNull::dangling();
1140        self.len = 0;
1141        self.capacity = 0;
1142
1143        IntoIter {
1144            data: NonNull::new(ptr).unwrap(),
1145            start: ptr,
1146            end: unsafe { ptr.add(len) },
1147            capacity,
1148        }
1149    }
1150}
1151
1152impl<'a, T> IntoIterator for &'a LimitedSizeVec<T> {
1153    type Item = &'a T;
1154    type IntoIter = std::slice::Iter<'a, T>;
1155
1156    /// Creates an iterator over references to the elements of the vector.
1157    ///
1158    /// # Examples
1159    ///
1160    /// ```rust
1161    /// # use qudit_core::LimitedSizeVec;
1162    ///
1163    /// let mut vec = LimitedSizeVec::new();
1164    /// vec.push(1);
1165    /// vec.push(2);
1166    ///
1167    /// for item in &vec {
1168    ///     println!("{}", item);
1169    /// }
1170    /// ```
1171    #[inline]
1172    fn into_iter(self) -> Self::IntoIter {
1173        self.as_slice().iter()
1174    }
1175}
1176
1177impl<'a, T> IntoIterator for &'a mut LimitedSizeVec<T> {
1178    type Item = &'a mut T;
1179    type IntoIter = std::slice::IterMut<'a, T>;
1180
1181    /// Creates an iterator over mutable references to the elements of the vector.
1182    ///
1183    /// # Examples
1184    ///
1185    /// ```rust
1186    /// # use qudit_core::LimitedSizeVec;
1187    ///
1188    /// let mut vec = LimitedSizeVec::new();
1189    /// vec.push(1);
1190    /// vec.push(2);
1191    ///
1192    /// for item in &mut vec {
1193    ///     *item *= 2;
1194    /// }
1195    /// assert_eq!(vec.as_slice(), [2, 4]);
1196    /// ```
1197    #[inline]
1198    fn into_iter(self) -> Self::IntoIter {
1199        self.as_slice_mut().iter_mut()
1200    }
1201}
1202// Safety: LimitedSizeVec<T> is Send if T is Send
1203unsafe impl<T: Send> Send for LimitedSizeVec<T> {}
1204
1205// Safety: LimitedSizeVec<T> is Sync if T is Sync
1206unsafe impl<T: Sync> Sync for LimitedSizeVec<T> {}
1207
1208impl<T> Drop for LimitedSizeVec<T> {
1209    /// Cleans up the vector's memory and drops all elements.
1210    fn drop(&mut self) {
1211        if self.capacity > 0 {
1212            // Drop all elements
1213            for i in 0..self.len {
1214                unsafe {
1215                    std::ptr::drop_in_place(self.data.as_ptr().add(i as usize));
1216                }
1217            }
1218
1219            // Deallocate memory
1220            unsafe {
1221                dealloc(
1222                    self.data.as_ptr() as *mut u8,
1223                    Layout::array::<T>(self.capacity as usize).unwrap(),
1224                );
1225            }
1226        }
1227    }
1228}
1229
1230#[cfg(test)]
1231mod tests {
1232    use super::*;
1233
1234    #[test]
1235    fn test_new_vector_creation() {
1236        let vec: LimitedSizeVec<i32> = LimitedSizeVec::new();
1237        assert_eq!(vec.len(), 0);
1238        assert_eq!(vec.capacity(), DEFAULT_CAPACITY as usize);
1239        assert!(vec.is_empty());
1240    }
1241
1242    #[test]
1243    fn test_vector_with_custom_capacity() {
1244        let vec: LimitedSizeVec<i32> = LimitedSizeVec::new_with_capacity(50);
1245        assert_eq!(vec.len(), 0);
1246        assert_eq!(vec.capacity(), 50);
1247        assert!(vec.is_empty());
1248    }
1249
1250    #[test]
1251    #[should_panic(expected = "Cannot create vector with zero capacity")]
1252    fn test_zero_capacity_panics() {
1253        LimitedSizeVec::<i32>::new_with_capacity(0);
1254    }
1255
1256    #[test]
1257    fn test_push_and_access_elements() {
1258        let mut vec = LimitedSizeVec::new();
1259        vec.push(1);
1260        vec.push(2);
1261        vec.push(3);
1262
1263        assert_eq!(vec.len(), 3);
1264        assert!(!vec.is_empty());
1265        assert_eq!(vec[0], 1);
1266        assert_eq!(vec[1], 2);
1267        assert_eq!(vec[2], 3);
1268    }
1269
1270    #[test]
1271    fn test_get_method_bounds_checking() {
1272        let mut vec = LimitedSizeVec::new();
1273        vec.push("hello");
1274        vec.push("world");
1275
1276        assert_eq!(vec.get(0), Some(&"hello"));
1277        assert_eq!(vec.get(1), Some(&"world"));
1278        assert_eq!(vec.get(2), None);
1279        assert_eq!(vec.get(100), None);
1280    }
1281
1282    #[test]
1283    fn test_get_mut_method() {
1284        let mut vec = LimitedSizeVec::new();
1285        vec.push(String::from("hello"));
1286
1287        if let Some(element) = vec.get_mut(0) {
1288            element.push_str(" world");
1289        }
1290
1291        assert_eq!(vec[0], "hello world");
1292        assert_eq!(vec.get_mut(1), None);
1293    }
1294
1295    #[test]
1296    fn test_capacity_growth_on_push() {
1297        let mut vec = LimitedSizeVec::new_with_capacity(2);
1298        assert_eq!(vec.capacity(), 2);
1299
1300        vec.push(1);
1301        vec.push(2);
1302        assert_eq!(vec.capacity(), 2);
1303
1304        // This should trigger growth
1305        vec.push(3);
1306        assert_eq!(vec.capacity(), 4);
1307        assert_eq!(vec.len(), 3);
1308    }
1309
1310    #[test]
1311    fn test_as_slice_operations() {
1312        let mut vec = LimitedSizeVec::new();
1313        vec.push(3);
1314        vec.push(1);
1315        vec.push(4);
1316        vec.push(1);
1317        vec.push(5);
1318
1319        let slice = vec.as_slice();
1320        assert_eq!(slice, [3, 1, 4, 1, 5]);
1321
1322        let mut_slice = vec.as_slice_mut();
1323        mut_slice[0] = 10;
1324        assert_eq!(vec[0], 10);
1325    }
1326
1327    #[test]
1328    fn test_sort_method() {
1329        let mut vec = LimitedSizeVec::new();
1330        vec.push(3);
1331        vec.push(1);
1332        vec.push(4);
1333        vec.push(1);
1334        vec.push(5);
1335
1336        vec.sort();
1337        assert_eq!(vec.as_slice(), [1, 1, 3, 4, 5]);
1338    }
1339
1340    #[test]
1341    fn test_clear_method() {
1342        let mut vec = LimitedSizeVec::new();
1343        vec.push(1);
1344        vec.push(2);
1345        vec.push(3);
1346
1347        let old_capacity = vec.capacity();
1348        vec.clear();
1349
1350        assert_eq!(vec.len(), 0);
1351        assert!(vec.is_empty());
1352        assert_eq!(vec.capacity(), old_capacity); // Capacity preserved
1353    }
1354
1355    #[test]
1356    fn test_take_method() {
1357        let mut vec1 = LimitedSizeVec::new();
1358        vec1.push("hello");
1359        vec1.push("world");
1360
1361        let vec2 = vec1.take();
1362
1363        assert_eq!(vec1.len(), 0);
1364        assert!(vec1.is_empty());
1365        assert_eq!(vec2.len(), 2);
1366        assert_eq!(vec2[0], "hello");
1367        assert_eq!(vec2[1], "world");
1368    }
1369
1370    #[test]
1371    fn test_clone_implementation() {
1372        let mut vec1 = LimitedSizeVec::new();
1373        vec1.push(String::from("hello"));
1374        vec1.push(String::from("world"));
1375
1376        let vec2 = vec1.clone();
1377
1378        assert_eq!(vec1.len(), vec2.len());
1379        assert_eq!(vec1.capacity(), vec2.capacity());
1380        assert_eq!(vec1[0], vec2[0]);
1381        assert_eq!(vec1[1], vec2[1]);
1382
1383        // Verify they're independent
1384        drop(vec1);
1385        assert_eq!(vec2.len(), 2);
1386    }
1387
1388    #[test]
1389    fn test_to_owned_method() {
1390        let mut vec1 = LimitedSizeVec::new();
1391        vec1.push("test".to_string());
1392
1393        let vec2 = vec1.to_owned();
1394        assert_eq!(vec1.len(), vec2.len());
1395        assert_eq!(vec1[0], vec2[0]);
1396    }
1397
1398    #[test]
1399    fn test_deref_operations() {
1400        let mut vec = LimitedSizeVec::new();
1401        vec.push(1);
1402        vec.push(2);
1403        vec.push(3);
1404
1405        // Test Deref to slice
1406        let slice: &[i32] = &vec;
1407        assert_eq!(slice.len(), 3);
1408        assert_eq!(slice[0], 1);
1409
1410        // Test DerefMut to slice
1411        let slice_mut: &mut [i32] = &mut vec;
1412        slice_mut[0] = 10;
1413        assert_eq!(vec[0], 10);
1414    }
1415
1416    #[test]
1417    fn test_from_vec_conversion() {
1418        let std_vec = vec![1, 2, 3, 4, 5];
1419        let limited_vec: LimitedSizeVec<i32> = LimitedSizeVec::from(std_vec);
1420
1421        assert_eq!(limited_vec.len(), 5);
1422        assert_eq!(limited_vec.as_slice(), [1, 2, 3, 4, 5]);
1423        assert!(limited_vec.capacity() >= 5);
1424    }
1425
1426    #[test]
1427    fn test_from_slice_conversion() {
1428        let slice = [1, 2, 3];
1429        let limited_vec: LimitedSizeVec<i32> = LimitedSizeVec::from(&slice[..]);
1430
1431        assert_eq!(limited_vec.len(), 3);
1432        assert_eq!(limited_vec.as_slice(), [1, 2, 3]);
1433    }
1434
1435    #[test]
1436    fn test_to_vec_conversion() {
1437        let mut limited_vec = LimitedSizeVec::new();
1438        limited_vec.push(1);
1439        limited_vec.push(2);
1440        limited_vec.push(3);
1441
1442        let std_vec: Vec<i32> = Vec::from(limited_vec);
1443        assert_eq!(std_vec, [1, 2, 3]);
1444    }
1445
1446    #[test]
1447    fn test_as_ref_and_as_mut() {
1448        let mut vec = LimitedSizeVec::new();
1449        vec.push("hello");
1450        vec.push("world");
1451
1452        let slice_ref: &[&str] = vec.as_ref();
1453        assert_eq!(slice_ref, ["hello", "world"]);
1454
1455        let slice_mut: &mut [&str] = vec.as_mut();
1456        slice_mut[0] = "goodbye";
1457        assert_eq!(vec[0], "goodbye");
1458    }
1459
1460    #[test]
1461    fn test_debug_formatting() {
1462        let mut vec = LimitedSizeVec::new();
1463        vec.push(1);
1464        vec.push(2);
1465
1466        let debug_str = format!("{:?}", vec);
1467        assert_eq!(debug_str, "[1, 2]");
1468    }
1469
1470    #[test]
1471    fn test_empty_vector_operations() {
1472        let vec: LimitedSizeVec<i32> = LimitedSizeVec::new();
1473        assert_eq!(vec.len(), 0);
1474        assert!(vec.is_empty());
1475        assert_eq!(vec.get(0), None);
1476    }
1477
1478    #[test]
1479    fn test_large_capacity_vector() {
1480        let vec: LimitedSizeVec<u8> = LimitedSizeVec::new_with_capacity(1000);
1481        assert_eq!(vec.capacity(), 1000);
1482        assert_eq!(vec.len(), 0);
1483    }
1484
1485    #[test]
1486    fn test_drop_behavior() {
1487        use std::rc::Rc;
1488
1489        let item = Rc::new("test");
1490        assert_eq!(Rc::strong_count(&item), 1);
1491
1492        {
1493            let mut vec = LimitedSizeVec::new();
1494            vec.push(item.clone());
1495            assert_eq!(Rc::strong_count(&item), 2);
1496        } // vec is dropped here
1497
1498        assert_eq!(Rc::strong_count(&item), 1);
1499    }
1500
1501    #[test]
1502    fn test_pop_method() {
1503        let mut vec = LimitedSizeVec::new();
1504        assert_eq!(vec.pop(), None);
1505
1506        vec.push(1);
1507        vec.push(2);
1508        vec.push(3);
1509
1510        assert_eq!(vec.pop(), Some(3));
1511        assert_eq!(vec.len(), 2);
1512        assert_eq!(vec.pop(), Some(2));
1513        assert_eq!(vec.pop(), Some(1));
1514        assert_eq!(vec.pop(), None);
1515        assert_eq!(vec.len(), 0);
1516    }
1517
1518    #[test]
1519    fn test_remove_method() {
1520        let mut vec = LimitedSizeVec::new();
1521        vec.push("a");
1522        vec.push("b");
1523        vec.push("c");
1524        vec.push("d");
1525
1526        // Remove from middle
1527        assert_eq!(vec.remove(1), "b");
1528        assert_eq!(vec.as_slice(), ["a", "c", "d"]);
1529
1530        // Remove from end
1531        assert_eq!(vec.remove(2), "d");
1532        assert_eq!(vec.as_slice(), ["a", "c"]);
1533
1534        // Remove from start
1535        assert_eq!(vec.remove(0), "a");
1536        assert_eq!(vec.as_slice(), ["c"]);
1537    }
1538
1539    #[test]
1540    #[should_panic(expected = "removal index (is 5) should be < len (is 2)")]
1541    fn test_remove_out_of_bounds() {
1542        let mut vec = LimitedSizeVec::new();
1543        vec.push(1);
1544        vec.push(2);
1545        vec.remove(5);
1546    }
1547
1548    #[test]
1549    fn test_insert_method() {
1550        let mut vec = LimitedSizeVec::new();
1551        vec.push("a");
1552        vec.push("c");
1553
1554        // Insert in middle
1555        vec.insert(1, "b");
1556        assert_eq!(vec.as_slice(), ["a", "b", "c"]);
1557
1558        // Insert at beginning
1559        vec.insert(0, "start");
1560        assert_eq!(vec.as_slice(), ["start", "a", "b", "c"]);
1561
1562        // Insert at end
1563        vec.insert(vec.len(), "end");
1564        assert_eq!(vec.as_slice(), ["start", "a", "b", "c", "end"]);
1565    }
1566
1567    #[test]
1568    #[should_panic(expected = "insertion index (is 5) should be <= len (is 2)")]
1569    fn test_insert_out_of_bounds() {
1570        let mut vec = LimitedSizeVec::new();
1571        vec.push(1);
1572        vec.push(2);
1573        vec.insert(5, 3);
1574    }
1575
1576    #[test]
1577    fn test_truncate_method() {
1578        let mut vec = LimitedSizeVec::new();
1579        vec.push(1);
1580        vec.push(2);
1581        vec.push(3);
1582        vec.push(4);
1583        vec.push(5);
1584
1585        let old_capacity = vec.capacity();
1586        vec.truncate(3);
1587
1588        assert_eq!(vec.len(), 3);
1589        assert_eq!(vec.as_slice(), [1, 2, 3]);
1590        assert_eq!(vec.capacity(), old_capacity); // Capacity preserved
1591
1592        // Truncate to 0
1593        vec.truncate(0);
1594        assert_eq!(vec.len(), 0);
1595        assert!(vec.is_empty());
1596
1597        // Truncate larger than length should do nothing
1598        vec.push(10);
1599        vec.truncate(10);
1600        assert_eq!(vec.len(), 1);
1601        assert_eq!(vec[0], 10);
1602    }
1603
1604    #[test]
1605    fn test_resize_method() {
1606        let mut vec = LimitedSizeVec::new();
1607        vec.push(1);
1608
1609        // Resize up
1610        vec.resize(4, 42);
1611        assert_eq!(vec.as_slice(), [1, 42, 42, 42]);
1612
1613        // Resize down
1614        vec.resize(2, 0);
1615        assert_eq!(vec.as_slice(), [1, 42]);
1616
1617        // Resize to same size
1618        vec.resize(2, 100);
1619        assert_eq!(vec.as_slice(), [1, 42]);
1620    }
1621
1622    #[test]
1623    fn test_extend_from_slice() {
1624        let mut vec = LimitedSizeVec::new();
1625        vec.push(1);
1626
1627        vec.extend_from_slice(&[2, 3, 4]);
1628        assert_eq!(vec.as_slice(), [1, 2, 3, 4]);
1629
1630        vec.extend_from_slice(&[]);
1631        assert_eq!(vec.as_slice(), [1, 2, 3, 4]);
1632
1633        vec.extend_from_slice(&[5, 6]);
1634        assert_eq!(vec.as_slice(), [1, 2, 3, 4, 5, 6]);
1635    }
1636
1637    #[test]
1638    fn test_reserve_method() {
1639        let mut vec = LimitedSizeVec::new();
1640        assert_eq!(vec.capacity(), 8);
1641
1642        vec.reserve(50);
1643        assert!(vec.capacity() >= 50);
1644
1645        let old_capacity = vec.capacity();
1646        vec.reserve(10); // Less than current, should do nothing
1647        assert_eq!(vec.capacity(), old_capacity);
1648
1649        // Test with existing elements
1650        vec.push(1);
1651        vec.push(2);
1652        vec.reserve(100);
1653        assert!(vec.capacity() >= 100);
1654        assert_eq!(vec.as_slice(), [1, 2]);
1655    }
1656
1657    #[test]
1658    fn test_push_unchecked() {
1659        let mut vec = LimitedSizeVec::new_with_capacity(10);
1660
1661        unsafe {
1662            vec.push_unchecked(1);
1663            vec.push_unchecked(2);
1664            vec.push_unchecked(3);
1665        }
1666
1667        assert_eq!(vec.len(), 3);
1668        assert_eq!(vec.as_slice(), [1, 2, 3]);
1669    }
1670
1671    #[test]
1672    fn test_get_unchecked_methods() {
1673        let mut vec = LimitedSizeVec::new();
1674        vec.push(String::from("hello"));
1675        vec.push(String::from("world"));
1676
1677        unsafe {
1678            assert_eq!(vec.get_unchecked(0), &"hello");
1679            assert_eq!(vec.get_unchecked(1), &"world");
1680
1681            vec.get_mut_unchecked(0).push_str(" there");
1682            assert_eq!(vec.get_unchecked(0), &"hello there");
1683        }
1684    }
1685
1686    #[test]
1687    fn test_from_iterator() {
1688        let iter = 0..5;
1689        let vec: LimitedSizeVec<i32> = iter.collect();
1690        assert_eq!(vec.len(), 5);
1691        assert_eq!(vec.as_slice(), [0, 1, 2, 3, 4]);
1692
1693        let empty_iter: std::vec::IntoIter<i32> = Vec::new().into_iter();
1694        let empty_vec: LimitedSizeVec<i32> = empty_iter.collect();
1695        assert_eq!(empty_vec.len(), 0);
1696    }
1697
1698    #[test]
1699    fn test_from_iterator_with_strings() {
1700        let iter = vec!["a".to_string(), "b".to_string(), "c".to_string()].into_iter();
1701        let vec: LimitedSizeVec<String> = iter.collect();
1702        assert_eq!(vec.len(), 3);
1703        assert_eq!(vec.as_slice(), ["a", "b", "c"]);
1704    }
1705
1706    #[test]
1707    fn test_into_iterator() {
1708        let mut vec = LimitedSizeVec::new();
1709        vec.push(1);
1710        vec.push(2);
1711        vec.push(3);
1712
1713        let collected: Vec<i32> = vec.into_iter().collect();
1714        assert_eq!(collected, [1, 2, 3]);
1715    }
1716
1717    #[test]
1718    fn test_iterator_double_ended() {
1719        let mut vec = LimitedSizeVec::new();
1720        vec.push(1);
1721        vec.push(2);
1722        vec.push(3);
1723
1724        let mut iter = vec.into_iter();
1725        assert_eq!(iter.next(), Some(1));
1726        assert_eq!(iter.next_back(), Some(3));
1727        assert_eq!(iter.next(), Some(2));
1728        assert_eq!(iter.next(), None);
1729        assert_eq!(iter.next_back(), None);
1730    }
1731
1732    #[test]
1733    fn test_borrowed_iterator() {
1734        let mut vec = LimitedSizeVec::new();
1735        vec.push(1);
1736        vec.push(2);
1737        vec.push(3);
1738
1739        let sum: i32 = (&vec).into_iter().sum();
1740        assert_eq!(sum, 6);
1741
1742        // Vector should still exist
1743        assert_eq!(vec.len(), 3);
1744    }
1745
1746    #[test]
1747    fn test_mutable_borrowed_iterator() {
1748        let mut vec = LimitedSizeVec::new();
1749        vec.push(1);
1750        vec.push(2);
1751        vec.push(3);
1752
1753        for item in &mut vec {
1754            *item *= 2;
1755        }
1756
1757        assert_eq!(vec.as_slice(), [2, 4, 6]);
1758    }
1759
1760    #[test]
1761    fn test_iterator_size_hint() {
1762        let mut vec = LimitedSizeVec::new();
1763        vec.push(1);
1764        vec.push(2);
1765        vec.push(3);
1766
1767        let iter = vec.into_iter();
1768        assert_eq!(iter.size_hint(), (3, Some(3)));
1769    }
1770
1771    #[test]
1772    fn test_contains_method() {
1773        let mut vec = LimitedSizeVec::new();
1774        vec.push(1);
1775        vec.push(2);
1776        vec.push(3);
1777
1778        assert!(vec.contains(&1));
1779        assert!(vec.contains(&2));
1780        assert!(vec.contains(&3));
1781        assert!(!vec.contains(&4));
1782        assert!(!vec.contains(&0));
1783    }
1784
1785    #[test]
1786    fn test_clear_optimized_for_copy_types() {
1787        // Test with Copy type (no drops needed)
1788        let mut vec: LimitedSizeVec<i32> = LimitedSizeVec::new();
1789        vec.push(1);
1790        vec.push(2);
1791        vec.push(3);
1792
1793        let old_capacity = vec.capacity();
1794        vec.clear();
1795
1796        assert_eq!(vec.len(), 0);
1797        assert_eq!(vec.capacity(), old_capacity);
1798
1799        // Test with non-Copy type (drops needed)
1800        let mut vec = LimitedSizeVec::new();
1801        vec.push(String::from("hello"));
1802        vec.push(String::from("world"));
1803
1804        let old_capacity = vec.capacity();
1805        vec.clear();
1806
1807        assert_eq!(vec.len(), 0);
1808        assert_eq!(vec.capacity(), old_capacity);
1809    }
1810
1811    #[test]
1812    fn test_memory_efficiency_compared_to_std_vec() {
1813        // Test that our struct is smaller than Vec on 64-bit systems
1814        use std::mem::size_of;
1815
1816        // LimitedSizeVec should be smaller due to u32 length/capacity
1817        let limited_size = size_of::<LimitedSizeVec<i32>>();
1818        let std_vec_size = size_of::<Vec<i32>>();
1819
1820        #[cfg(target_pointer_width = "64")]
1821        {
1822            // On 64-bit systems, our vector should be smaller
1823            assert!(limited_size <= std_vec_size);
1824        }
1825
1826        println!("LimitedSizeVec<i32> size: {} bytes", limited_size);
1827        println!("Vec<i32> size: {} bytes", std_vec_size);
1828    }
1829}