certeza/vec/mod.rs
1#![allow(unsafe_code)]
2//! # `TruenoVec` - A Growable Array Type with Verified Correctness
3//!
4//! This module provides `TruenoVec<T>`, a custom growable vector implementation
5//! that demonstrates the certeza framework's tiered testing approach:
6//!
7//! - **Tier 1**: Unit tests for basic functionality (sub-second feedback)
8//! - **Tier 2**: Property-based tests verifying algebraic properties (1-5 minutes)
9//! - **Tier 3**: Formal verification of critical invariants with Kani (hours)
10//!
11//! ## Safety Invariants
12//!
13//! The following invariants are maintained and formally verified:
14//!
15//! 1. `ptr` is either null or points to valid memory for `capacity` elements
16//! 2. `len <= capacity` at all times
17//! 3. Elements `[0..len)` are initialized
18//! 4. Elements `[len..capacity)` are uninitialized
19//!
20//! ## Risk Classification
21//!
22//! **Very High Risk** - Contains `unsafe` code for manual memory management.
23//! Full verification framework applied:
24//! - Property-based testing
25//! - 95%+ coverage requirement
26//! - >85% mutation score target
27//! - Formal verification of invariants
28//!
29//! ## Example
30//!
31//! ```rust
32//! use certeza::TruenoVec;
33//!
34//! let mut vec = TruenoVec::new();
35//! vec.push(1);
36//! vec.push(2);
37//! vec.push(3);
38//!
39//! assert_eq!(vec.len(), 3);
40//! assert_eq!(vec.get(1), Some(&2));
41//! assert_eq!(vec.pop(), Some(3));
42//! ```
43
44use std::alloc::{self, Layout};
45use std::marker::PhantomData;
46use std::ptr::{self, NonNull};
47
48/// A growable array type with verified correctness properties.
49///
50/// This implementation demonstrates asymptotic test effectiveness through:
51/// - 95%+ line coverage
52/// - >85% mutation score
53/// - Comprehensive property-based test suite
54/// - Formal verification of critical invariants
55///
56/// # Type Parameters
57///
58/// * `T` - The type of elements stored in the vector
59///
60/// # Safety
61///
62/// This type uses `unsafe` code for manual memory management. All safety
63/// invariants are formally verified using Kani and tested using property-based
64/// testing with proptest.
65///
66/// # Examples
67///
68/// ```rust
69/// use certeza::TruenoVec;
70///
71/// let mut v = TruenoVec::new();
72/// v.push(1);
73/// v.push(2);
74/// assert_eq!(v.len(), 2);
75/// assert_eq!(v.pop(), Some(2));
76/// ```
77pub struct TruenoVec<T> {
78 ptr: NonNull<T>,
79 len: usize,
80 capacity: usize,
81 _marker: PhantomData<T>,
82}
83
84// ============================================================================
85// Core Implementation
86// ============================================================================
87
88impl<T> TruenoVec<T> {
89 /// Creates a new, empty `TruenoVec<T>`.
90 ///
91 /// The vector will not allocate until elements are pushed onto it.
92 ///
93 /// # Complexity
94 ///
95 /// - Time: O(1)
96 /// - Space: O(1)
97 ///
98 /// # Examples
99 ///
100 /// ```rust
101 /// use certeza::TruenoVec;
102 ///
103 /// let mut vec: TruenoVec<i32> = TruenoVec::new();
104 /// assert_eq!(vec.len(), 0);
105 /// assert_eq!(vec.capacity(), 0);
106 /// ```
107 #[must_use]
108 pub const fn new() -> Self {
109 Self { ptr: NonNull::dangling(), len: 0, capacity: 0, _marker: PhantomData }
110 }
111
112 /// Creates a new, empty `TruenoVec<T>` with the specified capacity.
113 ///
114 /// The vector will be able to hold exactly `capacity` elements without
115 /// reallocating. If `capacity` is 0, the vector will not allocate.
116 ///
117 /// # Complexity
118 ///
119 /// - Time: O(n) where n is the capacity
120 /// - Space: O(n)
121 ///
122 /// # Panics
123 ///
124 /// Panics if the capacity exceeds `isize::MAX` bytes or if allocation fails.
125 ///
126 /// # Examples
127 ///
128 /// ```rust
129 /// use certeza::TruenoVec;
130 ///
131 /// let mut vec: TruenoVec<i32> = TruenoVec::with_capacity(10);
132 /// assert_eq!(vec.len(), 0);
133 /// assert_eq!(vec.capacity(), 10);
134 ///
135 /// // These pushes won't reallocate
136 /// for i in 0..10 {
137 /// vec.push(i);
138 /// }
139 /// assert_eq!(vec.capacity(), 10);
140 /// ```
141 #[must_use]
142 pub fn with_capacity(capacity: usize) -> Self {
143 if capacity == 0 {
144 Self::new()
145 } else {
146 let layout = Layout::array::<T>(capacity).expect("capacity overflow");
147 // SAFETY: layout has non-zero size
148 let ptr = unsafe {
149 let ptr = alloc::alloc(layout).cast::<T>();
150 NonNull::new(ptr).expect("allocation failed")
151 };
152 Self { ptr, len: 0, capacity, _marker: PhantomData }
153 }
154 }
155
156 /// Returns the number of elements in the vector.
157 ///
158 /// # Complexity
159 ///
160 /// O(1)
161 ///
162 /// # Examples
163 ///
164 /// ```rust
165 /// use certeza::TruenoVec;
166 ///
167 /// let mut vec = TruenoVec::new();
168 /// assert_eq!(vec.len(), 0);
169 /// vec.push(1);
170 /// assert_eq!(vec.len(), 1);
171 /// ```
172 #[must_use]
173 pub const fn len(&self) -> usize {
174 self.len
175 }
176
177 /// Returns `true` if the vector contains no elements.
178 ///
179 /// # Complexity
180 ///
181 /// O(1)
182 ///
183 /// # Examples
184 ///
185 /// ```rust
186 /// use certeza::TruenoVec;
187 ///
188 /// let mut vec = TruenoVec::new();
189 /// assert!(vec.is_empty());
190 /// vec.push(1);
191 /// assert!(!vec.is_empty());
192 /// ```
193 #[must_use]
194 pub const fn is_empty(&self) -> bool {
195 self.len == 0
196 }
197
198 /// Returns the number of elements the vector can hold without reallocating.
199 ///
200 /// # Complexity
201 ///
202 /// O(1)
203 ///
204 /// # Examples
205 ///
206 /// ```rust
207 /// use certeza::TruenoVec;
208 ///
209 /// let vec: TruenoVec<i32> = TruenoVec::with_capacity(10);
210 /// assert_eq!(vec.capacity(), 10);
211 /// ```
212 #[must_use]
213 pub const fn capacity(&self) -> usize {
214 self.capacity
215 }
216
217 /// Appends an element to the back of the vector.
218 ///
219 /// # Complexity
220 ///
221 /// - Amortized O(1) time
222 /// - Worst-case O(n) when reallocation is needed
223 ///
224 /// # Panics
225 ///
226 /// Panics if the new capacity exceeds `isize::MAX` bytes.
227 ///
228 /// # Examples
229 ///
230 /// ```rust
231 /// use certeza::TruenoVec;
232 ///
233 /// let mut vec = TruenoVec::new();
234 /// vec.push(1);
235 /// vec.push(2);
236 /// assert_eq!(vec.len(), 2);
237 /// assert_eq!(vec.get(0), Some(&1));
238 /// assert_eq!(vec.get(1), Some(&2));
239 /// ```
240 pub fn push(&mut self, value: T) {
241 if self.len == self.capacity {
242 self.grow();
243 }
244 // SAFETY: len < capacity after grow, ptr is valid
245 unsafe {
246 ptr::write(self.ptr.as_ptr().add(self.len), value);
247 }
248 self.len += 1;
249 }
250
251 /// Removes the last element from the vector and returns it, or `None` if empty.
252 ///
253 /// # Complexity
254 ///
255 /// O(1)
256 ///
257 /// # Examples
258 ///
259 /// ```rust
260 /// use certeza::TruenoVec;
261 ///
262 /// let mut vec = TruenoVec::new();
263 /// vec.push(1);
264 /// vec.push(2);
265 /// assert_eq!(vec.pop(), Some(2));
266 /// assert_eq!(vec.pop(), Some(1));
267 /// assert_eq!(vec.pop(), None);
268 /// ```
269 #[allow(clippy::missing_const_for_fn)] // Cannot be const due to ptr::read
270 pub fn pop(&mut self) -> Option<T> {
271 if self.len == 0 {
272 None
273 } else {
274 self.len -= 1;
275 // SAFETY: len was > 0, so len-1 is a valid initialized index
276 unsafe { Some(ptr::read(self.ptr.as_ptr().add(self.len))) }
277 }
278 }
279
280 /// Returns a reference to an element at the given index, or `None` if out of bounds.
281 ///
282 /// # Complexity
283 ///
284 /// O(1)
285 ///
286 /// # Examples
287 ///
288 /// ```rust
289 /// use certeza::TruenoVec;
290 ///
291 /// let mut vec = TruenoVec::new();
292 /// vec.push(10);
293 /// vec.push(20);
294 /// vec.push(30);
295 /// assert_eq!(vec.get(1), Some(&20));
296 /// assert_eq!(vec.get(3), None);
297 /// ```
298 #[must_use]
299 pub fn get(&self, index: usize) -> Option<&T> {
300 if index < self.len {
301 // SAFETY: index < len, so it's a valid initialized element
302 unsafe { Some(&*self.ptr.as_ptr().add(index)) }
303 } else {
304 None
305 }
306 }
307
308 /// Returns a mutable reference to an element at the given index, or `None` if out of bounds.
309 ///
310 /// # Complexity
311 ///
312 /// O(1)
313 ///
314 /// # Examples
315 ///
316 /// ```rust
317 /// use certeza::TruenoVec;
318 ///
319 /// let mut vec = TruenoVec::new();
320 /// vec.push(10);
321 /// vec.push(20);
322 /// if let Some(elem) = vec.get_mut(1) {
323 /// *elem = 25;
324 /// }
325 /// assert_eq!(vec.get(1), Some(&25));
326 /// ```
327 #[must_use]
328 pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
329 if index < self.len {
330 // SAFETY: index < len, so it's a valid initialized element
331 unsafe { Some(&mut *self.ptr.as_ptr().add(index)) }
332 } else {
333 None
334 }
335 }
336
337 /// Clears the vector, removing all values.
338 ///
339 /// This method removes all elements from the vector but does not change
340 /// its capacity. The allocated memory is retained for reuse.
341 ///
342 /// # Complexity
343 ///
344 /// O(n) where n is the number of elements
345 ///
346 /// # Examples
347 ///
348 /// ```rust
349 /// use certeza::TruenoVec;
350 ///
351 /// let mut vec = TruenoVec::new();
352 /// vec.push(1);
353 /// vec.push(2);
354 /// vec.push(3);
355 ///
356 /// let capacity = vec.capacity();
357 /// vec.clear();
358 ///
359 /// assert_eq!(vec.len(), 0);
360 /// assert_eq!(vec.capacity(), capacity); // Capacity unchanged
361 /// assert!(vec.is_empty());
362 /// ```
363 pub fn clear(&mut self) {
364 while self.pop().is_some() {}
365 }
366
367 /// Inserts an element at position `index`, shifting all elements after it
368 /// to the right.
369 ///
370 /// # Complexity
371 ///
372 /// - Time: O(n) where n is the number of elements after the insertion point
373 /// - Space: O(1) amortized (may reallocate if capacity is exceeded)
374 ///
375 /// # Panics
376 ///
377 /// Panics if `index > len()`.
378 ///
379 /// # Examples
380 ///
381 /// ```rust
382 /// use certeza::TruenoVec;
383 ///
384 /// let mut vec = TruenoVec::new();
385 /// vec.push(1);
386 /// vec.push(3);
387 /// vec.insert(1, 2); // Insert 2 at index 1
388 ///
389 /// assert_eq!(vec.get(0), Some(&1));
390 /// assert_eq!(vec.get(1), Some(&2));
391 /// assert_eq!(vec.get(2), Some(&3));
392 /// ```
393 pub fn insert(&mut self, index: usize, value: T) {
394 assert!(index <= self.len, "insertion index out of bounds");
395
396 if self.len == self.capacity {
397 self.grow();
398 }
399
400 // SAFETY: len < capacity after grow, index <= len
401 unsafe {
402 let ptr = self.ptr.as_ptr();
403 // Shift elements [index..len) one position to the right
404 if index < self.len {
405 ptr::copy(ptr.add(index), ptr.add(index + 1), self.len - index);
406 }
407 // Write the new value at index
408 ptr::write(ptr.add(index), value);
409 }
410
411 self.len += 1;
412 }
413
414 /// Removes and returns the element at position `index`, shifting all
415 /// elements after it to the left.
416 ///
417 /// # Complexity
418 ///
419 /// O(n) where n is the number of elements after the removal point
420 ///
421 /// # Panics
422 ///
423 /// Panics if `index >= len()`.
424 ///
425 /// # Examples
426 ///
427 /// ```rust
428 /// use certeza::TruenoVec;
429 ///
430 /// let mut vec = TruenoVec::new();
431 /// vec.push(1);
432 /// vec.push(2);
433 /// vec.push(3);
434 ///
435 /// let removed = vec.remove(1);
436 /// assert_eq!(removed, 2);
437 /// assert_eq!(vec.len(), 2);
438 /// assert_eq!(vec.get(0), Some(&1));
439 /// assert_eq!(vec.get(1), Some(&3));
440 /// ```
441 pub fn remove(&mut self, index: usize) -> T {
442 assert!(index < self.len, "removal index out of bounds");
443
444 // SAFETY: index < len, so it's a valid initialized element
445 unsafe {
446 let ptr = self.ptr.as_ptr();
447 // Read the value at index
448 let value = ptr::read(ptr.add(index));
449 // Shift elements [index+1..len) one position to the left
450 if index < self.len - 1 {
451 ptr::copy(ptr.add(index + 1), ptr.add(index), self.len - index - 1);
452 }
453 self.len -= 1;
454 value
455 }
456 }
457
458 /// Returns an immutable slice containing all elements of the vector.
459 ///
460 /// This provides a safe view into the vector's contents without copying.
461 ///
462 /// # Complexity
463 ///
464 /// O(1)
465 ///
466 /// # Examples
467 ///
468 /// ```rust
469 /// use certeza::TruenoVec;
470 ///
471 /// let mut vec = TruenoVec::new();
472 /// vec.push(1);
473 /// vec.push(2);
474 /// vec.push(3);
475 ///
476 /// let slice = vec.as_slice();
477 /// assert_eq!(slice, &[1, 2, 3]);
478 /// assert_eq!(slice.len(), 3);
479 /// ```
480 #[must_use]
481 pub const fn as_slice(&self) -> &[T] {
482 // SAFETY: ptr points to len initialized elements
483 unsafe { std::slice::from_raw_parts(self.ptr.as_ptr(), self.len) }
484 }
485
486 /// Returns a mutable slice containing all elements of the vector.
487 ///
488 /// This provides a safe mutable view into the vector's contents without copying.
489 ///
490 /// # Complexity
491 ///
492 /// O(1)
493 ///
494 /// # Examples
495 ///
496 /// ```rust
497 /// use certeza::TruenoVec;
498 ///
499 /// let mut vec = TruenoVec::new();
500 /// vec.push(1);
501 /// vec.push(2);
502 /// vec.push(3);
503 ///
504 /// let slice = vec.as_slice_mut();
505 /// slice[1] = 10;
506 /// assert_eq!(vec.get(1), Some(&10));
507 /// ```
508 #[must_use]
509 pub const fn as_slice_mut(&mut self) -> &mut [T] {
510 // SAFETY: ptr points to len initialized elements
511 unsafe { std::slice::from_raw_parts_mut(self.ptr.as_ptr(), self.len) }
512 }
513
514 /// Doubles the capacity of the vector.
515 ///
516 /// Uses a growth factor of 2x for exponential growth, ensuring amortized O(1) push.
517 ///
518 /// # Panics
519 ///
520 /// Panics if the new capacity exceeds `isize::MAX` bytes.
521 fn grow(&mut self) {
522 let new_capacity = if self.capacity == 0 {
523 1
524 } else {
525 self.capacity.checked_mul(2).expect("capacity overflow")
526 };
527
528 let new_layout = Layout::array::<T>(new_capacity).expect("capacity overflow");
529
530 let new_ptr = if self.capacity == 0 {
531 // SAFETY: new_layout has non-zero size
532 unsafe {
533 let ptr = alloc::alloc(new_layout).cast::<T>();
534 NonNull::new(ptr).expect("allocation failed")
535 }
536 } else {
537 let old_layout = Layout::array::<T>(self.capacity).expect("capacity overflow");
538 // SAFETY: ptr is valid, old_layout matches the current allocation
539 unsafe {
540 let ptr =
541 alloc::realloc(self.ptr.as_ptr().cast::<u8>(), old_layout, new_layout.size())
542 .cast::<T>();
543 NonNull::new(ptr).expect("allocation failed")
544 }
545 };
546
547 self.ptr = new_ptr;
548 self.capacity = new_capacity;
549 }
550}
551
552// ============================================================================
553// Trait Implementations
554// ============================================================================
555
556impl<T> Default for TruenoVec<T> {
557 fn default() -> Self {
558 Self::new()
559 }
560}
561
562impl<T> Drop for TruenoVec<T> {
563 fn drop(&mut self) {
564 // Drop all elements
565 while self.pop().is_some() {}
566
567 // Deallocate memory if capacity > 0
568 if self.capacity > 0 {
569 let layout = Layout::array::<T>(self.capacity).expect("capacity overflow");
570 // SAFETY: ptr was allocated with this layout, all elements dropped
571 unsafe {
572 alloc::dealloc(self.ptr.as_ptr().cast::<u8>(), layout);
573 }
574 }
575 }
576}
577
578// Thread safety: TruenoVec<T> is Send if T is Send
579unsafe impl<T: Send> Send for TruenoVec<T> {}
580
581// Thread safety: TruenoVec<T> is Sync if T is Sync
582unsafe impl<T: Sync> Sync for TruenoVec<T> {}
583
584// ============================================================================
585// Conversion Trait Implementations
586// ============================================================================
587
588impl<T> From<Vec<T>> for TruenoVec<T> {
589 /// Converts a `Vec<T>` into a `TruenoVec<T>`.
590 ///
591 /// This conversion takes ownership of the `Vec` and efficiently reuses
592 /// its underlying allocation by transferring elements one by one.
593 ///
594 /// # Complexity
595 ///
596 /// - Time: O(n) where n is the number of elements
597 /// - Space: O(n) for the new allocation (original Vec allocation is dropped)
598 ///
599 /// # Examples
600 ///
601 /// ```rust
602 /// use certeza::TruenoVec;
603 ///
604 /// let std_vec = vec![1, 2, 3, 4, 5];
605 /// let trueno_vec: TruenoVec<i32> = TruenoVec::from(std_vec);
606 ///
607 /// assert_eq!(trueno_vec.len(), 5);
608 /// assert_eq!(trueno_vec.get(0), Some(&1));
609 /// assert_eq!(trueno_vec.get(4), Some(&5));
610 /// ```
611 fn from(vec: Vec<T>) -> Self {
612 let mut trueno = Self::with_capacity(vec.len());
613 for item in vec {
614 trueno.push(item);
615 }
616 trueno
617 }
618}
619
620impl<T: Clone> From<&[T]> for TruenoVec<T> {
621 /// Converts a slice `&[T]` into a `TruenoVec<T>`.
622 ///
623 /// This conversion clones all elements from the slice into a new `TruenoVec`.
624 /// Requires `T: Clone` since we're creating owned copies.
625 ///
626 /// # Complexity
627 ///
628 /// - Time: O(n) where n is the number of elements
629 /// - Space: O(n)
630 ///
631 /// # Examples
632 ///
633 /// ```rust
634 /// use certeza::TruenoVec;
635 ///
636 /// let array = [1, 2, 3, 4, 5];
637 /// let slice: &[i32] = &array;
638 /// let trueno_vec: TruenoVec<i32> = TruenoVec::from(slice);
639 ///
640 /// assert_eq!(trueno_vec.len(), 5);
641 /// assert_eq!(trueno_vec.get(2), Some(&3));
642 /// ```
643 fn from(slice: &[T]) -> Self {
644 let mut trueno = Self::with_capacity(slice.len());
645 for item in slice {
646 trueno.push(item.clone());
647 }
648 trueno
649 }
650}
651
652impl<T> FromIterator<T> for TruenoVec<T> {
653 /// Creates a `TruenoVec<T>` from an iterator.
654 ///
655 /// This enables the `.collect()` method on iterators to produce a `TruenoVec`.
656 ///
657 /// # Complexity
658 ///
659 /// - Time: O(n) where n is the number of elements in the iterator
660 /// - Space: O(n)
661 ///
662 /// # Examples
663 ///
664 /// ```rust
665 /// use certeza::TruenoVec;
666 ///
667 /// let trueno_vec: TruenoVec<i32> = (0..10).collect();
668 ///
669 /// assert_eq!(trueno_vec.len(), 10);
670 /// assert_eq!(trueno_vec.get(5), Some(&5));
671 /// ```
672 ///
673 /// ```rust
674 /// use certeza::TruenoVec;
675 ///
676 /// let numbers = vec![1, 2, 3, 4, 5];
677 /// let doubled: TruenoVec<i32> = numbers.iter().map(|x| x * 2).collect();
678 ///
679 /// assert_eq!(doubled.len(), 5);
680 /// assert_eq!(doubled.get(0), Some(&2));
681 /// assert_eq!(doubled.get(4), Some(&10));
682 /// ```
683 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
684 let iter = iter.into_iter();
685 let (lower_bound, _) = iter.size_hint();
686 let mut trueno = Self::with_capacity(lower_bound);
687
688 for item in iter {
689 trueno.push(item);
690 }
691
692 trueno
693 }
694}
695
696impl<T> Extend<T> for TruenoVec<T> {
697 /// Extends a `TruenoVec<T>` with the contents of an iterator.
698 ///
699 /// This method appends all elements from the iterator to the end of the vector.
700 ///
701 /// # Complexity
702 ///
703 /// - Time: O(n) where n is the number of elements in the iterator
704 /// - Space: O(n) amortized
705 ///
706 /// # Examples
707 ///
708 /// ```rust
709 /// use certeza::TruenoVec;
710 ///
711 /// let mut vec = TruenoVec::new();
712 /// vec.push(1);
713 /// vec.push(2);
714 ///
715 /// vec.extend(vec![3, 4, 5]);
716 ///
717 /// assert_eq!(vec.len(), 5);
718 /// assert_eq!(vec.get(0), Some(&1));
719 /// assert_eq!(vec.get(4), Some(&5));
720 /// ```
721 ///
722 /// ```rust
723 /// use certeza::TruenoVec;
724 ///
725 /// let mut vec = TruenoVec::new();
726 /// vec.extend(0..10);
727 ///
728 /// assert_eq!(vec.len(), 10);
729 /// ```
730 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
731 let iter = iter.into_iter();
732 let (lower_bound, _) = iter.size_hint();
733
734 // Reserve space if we know the size hint
735 if lower_bound > 0 {
736 let needed_capacity = self.len.saturating_add(lower_bound);
737 while self.capacity < needed_capacity {
738 self.grow();
739 }
740 }
741
742 for item in iter {
743 self.push(item);
744 }
745 }
746}
747
748// ============================================================================
749// Iterator Implementations
750// ============================================================================
751
752/// Immutable iterator over `TruenoVec<T>`.
753///
754/// This struct is created by the `iter` method on `TruenoVec`.
755pub struct Iter<'a, T> {
756 ptr: *const T,
757 end: *const T,
758 _marker: PhantomData<&'a T>,
759}
760
761impl<'a, T> Iterator for Iter<'a, T> {
762 type Item = &'a T;
763
764 fn next(&mut self) -> Option<Self::Item> {
765 if self.ptr == self.end {
766 None
767 } else {
768 // SAFETY: ptr is valid and within bounds
769 unsafe {
770 let item = &*self.ptr;
771 self.ptr = self.ptr.add(1);
772 Some(item)
773 }
774 }
775 }
776
777 fn size_hint(&self) -> (usize, Option<usize>) {
778 let size = std::mem::size_of::<T>();
779 let len = if size == 0 { 0 } else { (self.end as usize - self.ptr as usize) / size };
780 (len, Some(len))
781 }
782}
783
784impl<T> ExactSizeIterator for Iter<'_, T> {}
785
786impl<T> DoubleEndedIterator for Iter<'_, T> {
787 fn next_back(&mut self) -> Option<Self::Item> {
788 if self.ptr == self.end {
789 None
790 } else {
791 // SAFETY: end-1 is valid and within bounds
792 unsafe {
793 self.end = self.end.sub(1);
794 Some(&*self.end)
795 }
796 }
797 }
798}
799
800/// Mutable iterator over `TruenoVec<T>`.
801///
802/// This struct is created by the `iter_mut` method on `TruenoVec`.
803pub struct IterMut<'a, T> {
804 ptr: *mut T,
805 end: *mut T,
806 _marker: PhantomData<&'a mut T>,
807}
808
809impl<'a, T> Iterator for IterMut<'a, T> {
810 type Item = &'a mut T;
811
812 fn next(&mut self) -> Option<Self::Item> {
813 if self.ptr == self.end {
814 None
815 } else {
816 // SAFETY: ptr is valid and within bounds
817 unsafe {
818 let item = &mut *self.ptr;
819 self.ptr = self.ptr.add(1);
820 Some(item)
821 }
822 }
823 }
824
825 fn size_hint(&self) -> (usize, Option<usize>) {
826 let size = std::mem::size_of::<T>();
827 let len = if size == 0 { 0 } else { (self.end as usize - self.ptr as usize) / size };
828 (len, Some(len))
829 }
830}
831
832impl<T> ExactSizeIterator for IterMut<'_, T> {}
833
834impl<T> DoubleEndedIterator for IterMut<'_, T> {
835 fn next_back(&mut self) -> Option<Self::Item> {
836 if self.ptr == self.end {
837 None
838 } else {
839 // SAFETY: end-1 is valid and within bounds
840 unsafe {
841 self.end = self.end.sub(1);
842 Some(&mut *self.end)
843 }
844 }
845 }
846}
847
848/// Consuming iterator over `TruenoVec<T>`.
849///
850/// This struct is created by the `into_iter` method on `TruenoVec`
851/// (provided by the `IntoIterator` trait).
852pub struct IntoIter<T> {
853 vec: TruenoVec<T>,
854 current: usize,
855}
856
857impl<T> Iterator for IntoIter<T> {
858 type Item = T;
859
860 fn next(&mut self) -> Option<Self::Item> {
861 if self.current < self.vec.len {
862 let index = self.current;
863 self.current += 1;
864 // SAFETY: index < len, so it's a valid initialized element
865 // We take ownership by reading, so the Drop impl won't try to drop it again
866 unsafe { Some(ptr::read(self.vec.ptr.as_ptr().add(index))) }
867 } else {
868 None
869 }
870 }
871
872 fn size_hint(&self) -> (usize, Option<usize>) {
873 let remaining = self.vec.len - self.current;
874 (remaining, Some(remaining))
875 }
876}
877
878impl<T> ExactSizeIterator for IntoIter<T> {}
879
880impl<T> Drop for IntoIter<T> {
881 fn drop(&mut self) {
882 // Drop all remaining unconsumed elements
883 while self.current < self.vec.len {
884 // SAFETY: current is bounded by vec.len, ptr is valid for vec.len elements
885 unsafe {
886 ptr::drop_in_place(self.vec.ptr.as_ptr().add(self.current));
887 }
888 self.current += 1;
889 }
890
891 // Now deallocate the memory (all elements have been dropped)
892 if self.vec.capacity > 0 {
893 let layout = Layout::array::<T>(self.vec.capacity).expect("capacity overflow");
894 // SAFETY: ptr was allocated with this layout and capacity > 0 guarantees valid alloc
895 unsafe {
896 alloc::dealloc(self.vec.ptr.as_ptr().cast::<u8>(), layout);
897 }
898 }
899
900 // Prevent the vec's Drop from running by setting capacity to 0
901 // This is safe because we've already handled deallocation
902 self.vec.capacity = 0;
903 self.vec.len = 0;
904 }
905}
906
907impl<T> TruenoVec<T> {
908 /// Returns an iterator over the vector.
909 ///
910 /// # Examples
911 ///
912 /// ```rust
913 /// use certeza::TruenoVec;
914 ///
915 /// let mut vec = TruenoVec::new();
916 /// vec.push(1);
917 /// vec.push(2);
918 /// vec.push(3);
919 ///
920 /// let mut iter = vec.iter();
921 /// assert_eq!(iter.next(), Some(&1));
922 /// assert_eq!(iter.next(), Some(&2));
923 /// assert_eq!(iter.next(), Some(&3));
924 /// assert_eq!(iter.next(), None);
925 /// ```
926 #[must_use]
927 pub const fn iter(&self) -> Iter<'_, T> {
928 // SAFETY: ptr and ptr+len are both valid
929 unsafe {
930 Iter {
931 ptr: self.ptr.as_ptr(),
932 end: self.ptr.as_ptr().add(self.len),
933 _marker: PhantomData,
934 }
935 }
936 }
937
938 /// Returns a mutable iterator over the vector.
939 ///
940 /// # Examples
941 ///
942 /// ```rust
943 /// use certeza::TruenoVec;
944 ///
945 /// let mut vec = TruenoVec::new();
946 /// vec.push(1);
947 /// vec.push(2);
948 /// vec.push(3);
949 ///
950 /// for elem in vec.iter_mut() {
951 /// *elem *= 2;
952 /// }
953 ///
954 /// assert_eq!(vec.get(0), Some(&2));
955 /// assert_eq!(vec.get(1), Some(&4));
956 /// assert_eq!(vec.get(2), Some(&6));
957 /// ```
958 #[must_use]
959 pub const fn iter_mut(&mut self) -> IterMut<'_, T> {
960 // SAFETY: ptr and ptr+len are both valid
961 unsafe {
962 IterMut {
963 ptr: self.ptr.as_ptr(),
964 end: self.ptr.as_ptr().add(self.len),
965 _marker: PhantomData,
966 }
967 }
968 }
969}
970
971impl<T> IntoIterator for TruenoVec<T> {
972 type Item = T;
973 type IntoIter = IntoIter<T>;
974
975 /// Consumes the vector and returns an iterator over its elements.
976 ///
977 /// # Examples
978 ///
979 /// ```rust
980 /// use certeza::TruenoVec;
981 ///
982 /// let mut vec = TruenoVec::new();
983 /// vec.push(1);
984 /// vec.push(2);
985 /// vec.push(3);
986 ///
987 /// let sum: i32 = vec.into_iter().sum();
988 /// assert_eq!(sum, 6);
989 /// ```
990 fn into_iter(self) -> Self::IntoIter {
991 IntoIter { vec: self, current: 0 }
992 }
993}
994
995impl<'a, T> IntoIterator for &'a TruenoVec<T> {
996 type Item = &'a T;
997 type IntoIter = Iter<'a, T>;
998
999 fn into_iter(self) -> Self::IntoIter {
1000 self.iter()
1001 }
1002}
1003
1004impl<'a, T> IntoIterator for &'a mut TruenoVec<T> {
1005 type Item = &'a mut T;
1006 type IntoIter = IterMut<'a, T>;
1007
1008 fn into_iter(self) -> Self::IntoIter {
1009 self.iter_mut()
1010 }
1011}
1012
1013// ============================================================================
1014// Index Trait Implementations
1015// ============================================================================
1016
1017impl<T> std::ops::Index<usize> for TruenoVec<T> {
1018 type Output = T;
1019
1020 /// Returns a reference to an element at the given index.
1021 ///
1022 /// # Panics
1023 ///
1024 /// Panics if the index is out of bounds.
1025 ///
1026 /// # Examples
1027 ///
1028 /// ```
1029 /// use certeza::TruenoVec;
1030 ///
1031 /// let mut vec = TruenoVec::new();
1032 /// vec.push(10);
1033 /// vec.push(20);
1034 /// vec.push(30);
1035 ///
1036 /// assert_eq!(vec[0], 10);
1037 /// assert_eq!(vec[1], 20);
1038 /// assert_eq!(vec[2], 30);
1039 /// ```
1040 fn index(&self, index: usize) -> &Self::Output {
1041 let len = self.len;
1042 self.get(index).unwrap_or_else(|| {
1043 panic!("index out of bounds: the len is {len} but the index is {index}")
1044 })
1045 }
1046}
1047
1048impl<T> std::ops::IndexMut<usize> for TruenoVec<T> {
1049 /// Returns a mutable reference to an element at the given index.
1050 ///
1051 /// # Panics
1052 ///
1053 /// Panics if the index is out of bounds.
1054 ///
1055 /// # Examples
1056 ///
1057 /// ```
1058 /// use certeza::TruenoVec;
1059 ///
1060 /// let mut vec = TruenoVec::new();
1061 /// vec.push(10);
1062 /// vec.push(20);
1063 /// vec.push(30);
1064 ///
1065 /// vec[1] = 25;
1066 /// assert_eq!(vec[1], 25);
1067 /// ```
1068 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
1069 let len = self.len;
1070 self.get_mut(index).unwrap_or_else(|| {
1071 panic!("index out of bounds: the len is {len} but the index is {index}")
1072 })
1073 }
1074}
1075
1076// ============================================================================
1077// Clone Trait Implementation
1078// ============================================================================
1079
1080impl<T: Clone> Clone for TruenoVec<T> {
1081 /// Creates a deep copy of the vector.
1082 ///
1083 /// # Examples
1084 ///
1085 /// ```
1086 /// use certeza::TruenoVec;
1087 ///
1088 /// let mut vec1 = TruenoVec::new();
1089 /// vec1.push(1);
1090 /// vec1.push(2);
1091 /// vec1.push(3);
1092 ///
1093 /// let mut vec2 = vec1.clone();
1094 ///
1095 /// // Modify vec2
1096 /// vec2.push(4);
1097 ///
1098 /// // vec1 is unchanged
1099 /// assert_eq!(vec1.len(), 3);
1100 /// assert_eq!(vec2.len(), 4);
1101 /// ```
1102 fn clone(&self) -> Self {
1103 let mut new_vec = Self::with_capacity(self.len);
1104 for elem in self {
1105 new_vec.push(elem.clone());
1106 }
1107 new_vec
1108 }
1109}
1110
1111// ============================================================================
1112// PartialEq and Eq Trait Implementations
1113// ============================================================================
1114
1115impl<T: PartialEq> PartialEq for TruenoVec<T> {
1116 /// Compares two vectors for equality.
1117 ///
1118 /// Two vectors are equal if they have the same length and all elements
1119 /// at corresponding indices are equal.
1120 ///
1121 /// # Examples
1122 ///
1123 /// ```
1124 /// use certeza::TruenoVec;
1125 ///
1126 /// let mut vec1 = TruenoVec::new();
1127 /// vec1.push(1);
1128 /// vec1.push(2);
1129 ///
1130 /// let mut vec2 = TruenoVec::new();
1131 /// vec2.push(1);
1132 /// vec2.push(2);
1133 ///
1134 /// assert_eq!(vec1, vec2);
1135 ///
1136 /// vec2.push(3);
1137 /// assert_ne!(vec1, vec2);
1138 /// ```
1139 fn eq(&self, other: &Self) -> bool {
1140 // First check lengths - fast path
1141 if self.len != other.len {
1142 return false;
1143 }
1144
1145 // Compare elements
1146 for i in 0..self.len {
1147 if self.get(i) != other.get(i) {
1148 return false;
1149 }
1150 }
1151
1152 true
1153 }
1154}
1155
1156impl<T: Eq> Eq for TruenoVec<T> {}
1157
1158// ============================================================================
1159// Debug Trait Implementation
1160// ============================================================================
1161
1162impl<T: std::fmt::Debug> std::fmt::Debug for TruenoVec<T> {
1163 /// Formats the vector for debugging output.
1164 ///
1165 /// # Examples
1166 ///
1167 /// ```
1168 /// use certeza::TruenoVec;
1169 ///
1170 /// let mut vec = TruenoVec::new();
1171 /// vec.push(1);
1172 /// vec.push(2);
1173 /// vec.push(3);
1174 ///
1175 /// assert_eq!(format!("{:?}", vec), "[1, 2, 3]");
1176 /// ```
1177 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1178 f.debug_list().entries(self.iter()).finish()
1179 }
1180}
1181
1182// ============================================================================
1183// Phase 3.1 Ergonomic Trait Implementations (Deref/AsRef)
1184// ============================================================================
1185
1186impl<T> std::ops::Deref for TruenoVec<T> {
1187 type Target = [T];
1188
1189 /// Dereferences the `TruenoVec<T>` to a slice `&[T]`.
1190 ///
1191 /// This allows `TruenoVec` to be used seamlessly with any function
1192 /// that accepts a slice, enabling automatic coercion and access to
1193 /// all slice methods.
1194 ///
1195 /// # Examples
1196 ///
1197 /// ```
1198 /// use certeza::TruenoVec;
1199 ///
1200 /// let mut vec = TruenoVec::new();
1201 /// vec.push(1);
1202 /// vec.push(2);
1203 /// vec.push(3);
1204 ///
1205 /// // Deref coercion allows slice methods
1206 /// assert_eq!(vec.len(), 3);
1207 /// assert_eq!(vec.first(), Some(&1));
1208 /// assert_eq!(vec.last(), Some(&3));
1209 ///
1210 /// // Works with functions expecting slices
1211 /// fn sum_slice(s: &[i32]) -> i32 {
1212 /// s.iter().sum()
1213 /// }
1214 /// assert_eq!(sum_slice(&vec), 6);
1215 /// ```
1216 fn deref(&self) -> &Self::Target {
1217 self.as_slice()
1218 }
1219}
1220
1221impl<T> std::ops::DerefMut for TruenoVec<T> {
1222 /// Mutably dereferences the `TruenoVec<T>` to a mutable slice `&mut [T]`.
1223 ///
1224 /// This allows mutable access to slice methods through deref coercion.
1225 ///
1226 /// # Examples
1227 ///
1228 /// ```
1229 /// use certeza::TruenoVec;
1230 ///
1231 /// let mut vec = TruenoVec::new();
1232 /// vec.push(3);
1233 /// vec.push(1);
1234 /// vec.push(2);
1235 ///
1236 /// // DerefMut coercion allows mutable slice methods
1237 /// vec.sort();
1238 /// assert_eq!(vec.as_slice(), &[1, 2, 3]);
1239 ///
1240 /// vec.reverse();
1241 /// assert_eq!(vec.as_slice(), &[3, 2, 1]);
1242 /// ```
1243 fn deref_mut(&mut self) -> &mut Self::Target {
1244 self.as_slice_mut()
1245 }
1246}
1247
1248impl<T> AsRef<[T]> for TruenoVec<T> {
1249 /// Returns a reference to the vector's contents as a slice.
1250 ///
1251 /// This enables `TruenoVec` to be used with generic functions that
1252 /// accept `AsRef<[T]>` bounds, a common pattern in the Rust standard library.
1253 ///
1254 /// # Examples
1255 ///
1256 /// ```
1257 /// use certeza::TruenoVec;
1258 ///
1259 /// let mut vec = TruenoVec::new();
1260 /// vec.push(1);
1261 /// vec.push(2);
1262 /// vec.push(3);
1263 ///
1264 /// // Works with generic functions using AsRef<[T]>
1265 /// fn process<T: AsRef<[i32]>>(data: T) -> i32 {
1266 /// data.as_ref().iter().sum()
1267 /// }
1268 ///
1269 /// assert_eq!(process(&vec), 6);
1270 /// assert_eq!(process(vec![1, 2, 3]), 6);
1271 /// ```
1272 fn as_ref(&self) -> &[T] {
1273 self.as_slice()
1274 }
1275}
1276
1277impl<T> AsMut<[T]> for TruenoVec<T> {
1278 /// Returns a mutable reference to the vector's contents as a slice.
1279 ///
1280 /// This enables `TruenoVec` to be used with generic functions that
1281 /// accept `AsMut<[T]>` bounds, enabling mutable slice operations.
1282 ///
1283 /// # Examples
1284 ///
1285 /// ```
1286 /// use certeza::TruenoVec;
1287 ///
1288 /// let mut vec = TruenoVec::new();
1289 /// vec.push(1);
1290 /// vec.push(2);
1291 /// vec.push(3);
1292 ///
1293 /// // Works with generic functions using AsMut<[T]>
1294 /// fn double_in_place<T: AsMut<[i32]>>(mut data: T) {
1295 /// for x in data.as_mut() {
1296 /// *x *= 2;
1297 /// }
1298 /// }
1299 ///
1300 /// double_in_place(&mut vec);
1301 /// assert_eq!(vec.as_slice(), &[2, 4, 6]);
1302 /// ```
1303 fn as_mut(&mut self) -> &mut [T] {
1304 self.as_slice_mut()
1305 }
1306}
1307
1308impl<T> AsRef<Self> for TruenoVec<T> {
1309 /// Returns a reference to self.
1310 ///
1311 /// This implementation allows `TruenoVec` to work with APIs that
1312 /// require `AsRef<TruenoVec<T>>`.
1313 ///
1314 /// # Examples
1315 ///
1316 /// ```
1317 /// use certeza::TruenoVec;
1318 ///
1319 /// let vec = TruenoVec::from(vec![1, 2, 3]);
1320 /// let vec_ref: &TruenoVec<i32> = vec.as_ref();
1321 /// assert_eq!(vec_ref.len(), 3);
1322 /// ```
1323 fn as_ref(&self) -> &Self {
1324 self
1325 }
1326}
1327
1328impl<T> AsMut<Self> for TruenoVec<T> {
1329 /// Returns a mutable reference to self.
1330 ///
1331 /// This implementation allows `TruenoVec` to work with APIs that
1332 /// require `AsMut<TruenoVec<T>>`.
1333 ///
1334 /// # Examples
1335 ///
1336 /// ```
1337 /// use certeza::TruenoVec;
1338 ///
1339 /// let mut vec = TruenoVec::from(vec![1, 2, 3]);
1340 /// let vec_mut: &mut TruenoVec<i32> = vec.as_mut();
1341 /// vec_mut.push(4);
1342 /// assert_eq!(vec_mut.len(), 4);
1343 /// ```
1344 fn as_mut(&mut self) -> &mut Self {
1345 self
1346 }
1347}
1348
1349// ============================================================================
1350// Phase 3.2 Comparison and Hash Trait Implementations
1351// ============================================================================
1352
1353impl<T: PartialOrd> PartialOrd for TruenoVec<T> {
1354 /// Compares two vectors lexicographically.
1355 ///
1356 /// Vectors are compared element-by-element from left to right.
1357 /// The first mismatching element determines the ordering.
1358 /// If all elements match but one vector is shorter, the shorter vector is less.
1359 ///
1360 /// # Examples
1361 ///
1362 /// ```
1363 /// use certeza::TruenoVec;
1364 ///
1365 /// let mut vec1 = TruenoVec::new();
1366 /// vec1.push(1);
1367 /// vec1.push(2);
1368 ///
1369 /// let mut vec2 = TruenoVec::new();
1370 /// vec2.push(1);
1371 /// vec2.push(3);
1372 ///
1373 /// assert!(vec1 < vec2);
1374 /// assert!(vec2 > vec1);
1375 ///
1376 /// let mut vec3 = TruenoVec::new();
1377 /// vec3.push(1);
1378 /// assert!(vec3 < vec1); // Shorter vector is less
1379 /// ```
1380 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
1381 self.as_slice().partial_cmp(other.as_slice())
1382 }
1383
1384 fn lt(&self, other: &Self) -> bool {
1385 self.as_slice() < other.as_slice()
1386 }
1387
1388 fn le(&self, other: &Self) -> bool {
1389 self.as_slice() <= other.as_slice()
1390 }
1391
1392 fn gt(&self, other: &Self) -> bool {
1393 self.as_slice() > other.as_slice()
1394 }
1395
1396 fn ge(&self, other: &Self) -> bool {
1397 self.as_slice() >= other.as_slice()
1398 }
1399}
1400
1401impl<T: Ord> Ord for TruenoVec<T> {
1402 /// Returns the total ordering between two vectors.
1403 ///
1404 /// This provides a total ordering for vectors where `T: Ord`,
1405 /// enabling use in `BTreeMap` and `BTreeSet` as keys, and
1406 /// allowing sorting of vectors.
1407 ///
1408 /// # Examples
1409 ///
1410 /// ```
1411 /// use certeza::TruenoVec;
1412 /// use std::cmp::Ordering;
1413 ///
1414 /// let mut vec1 = TruenoVec::new();
1415 /// vec1.push(1);
1416 /// vec1.push(2);
1417 ///
1418 /// let mut vec2 = TruenoVec::new();
1419 /// vec2.push(1);
1420 /// vec2.push(3);
1421 ///
1422 /// assert_eq!(vec1.cmp(&vec2), Ordering::Less);
1423 ///
1424 /// // Can be used for sorting
1425 /// let mut vecs = vec![vec2.clone(), vec1.clone()];
1426 /// vecs.sort();
1427 /// assert_eq!(vecs[0], vec1);
1428 /// assert_eq!(vecs[1], vec2);
1429 /// ```
1430 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
1431 self.as_slice().cmp(other.as_slice())
1432 }
1433}
1434
1435impl<T: std::hash::Hash> std::hash::Hash for TruenoVec<T> {
1436 /// Hashes the vector by hashing all its elements in order.
1437 ///
1438 /// This enables `TruenoVec` to be used as keys in `HashMap` and
1439 /// values in `HashSet`, provided `T: Hash`.
1440 ///
1441 /// # Examples
1442 ///
1443 /// ```
1444 /// use certeza::TruenoVec;
1445 /// use std::collections::HashMap;
1446 ///
1447 /// let mut map = HashMap::new();
1448 ///
1449 /// let mut key = TruenoVec::new();
1450 /// key.push(1);
1451 /// key.push(2);
1452 /// key.push(3);
1453 ///
1454 /// map.insert(key.clone(), "value");
1455 /// assert_eq!(map.get(&key), Some(&"value"));
1456 ///
1457 /// // Different vectors have different hashes
1458 /// let mut key2 = TruenoVec::new();
1459 /// key2.push(1);
1460 /// key2.push(2);
1461 /// assert_eq!(map.get(&key2), None);
1462 /// ```
1463 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1464 // Hash the length first (same as std::Vec)
1465 self.len.hash(state);
1466 // Hash each element
1467 for elem in self {
1468 elem.hash(state);
1469 }
1470 }
1471}
1472
1473// ============================================================================
1474// Phase 3.3: Display and Borrow Traits (Polish & Advanced Use Cases)
1475// ============================================================================
1476
1477/// Display trait for user-friendly formatting
1478///
1479/// Formats the vector as `[elem1, elem2, ...]` similar to `std::Vec`.
1480///
1481/// # Examples
1482///
1483/// ```
1484/// use certeza::TruenoVec;
1485///
1486/// let vec = TruenoVec::from(vec![1, 2, 3]);
1487/// assert_eq!(format!("{}", vec), "[1, 2, 3]");
1488/// ```
1489impl<T: std::fmt::Display> std::fmt::Display for TruenoVec<T> {
1490 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1491 write!(f, "[")?;
1492 for (i, elem) in self.iter().enumerate() {
1493 if i > 0 {
1494 write!(f, ", ")?;
1495 }
1496 write!(f, "{elem}")?;
1497 }
1498 write!(f, "]")
1499 }
1500}
1501
1502/// Borrow<[T]> trait for advanced borrowing patterns
1503///
1504/// Enables using `TruenoVec` with APIs that accept `Borrow<[T]>` bounds,
1505/// particularly useful for `HashMap` and `BTreeMap` lookups.
1506///
1507/// # Examples
1508///
1509/// ```
1510/// use certeza::TruenoVec;
1511/// use std::borrow::Borrow;
1512///
1513/// let vec = TruenoVec::from(vec![1, 2, 3]);
1514/// let slice: &[i32] = vec.borrow();
1515/// assert_eq!(slice, &[1, 2, 3]);
1516/// ```
1517impl<T> std::borrow::Borrow<[T]> for TruenoVec<T> {
1518 fn borrow(&self) -> &[T] {
1519 self.as_slice()
1520 }
1521}
1522
1523/// `BorrowMut<[T]>` trait for advanced mutable borrowing patterns
1524///
1525/// Enables using `TruenoVec` with APIs that accept `BorrowMut<[T]>` bounds.
1526///
1527/// # Examples
1528///
1529/// ```
1530/// use certeza::TruenoVec;
1531/// use std::borrow::BorrowMut;
1532///
1533/// let mut vec = TruenoVec::from(vec![1, 2, 3]);
1534/// let slice: &mut [i32] = vec.borrow_mut();
1535/// slice[0] = 10;
1536/// assert_eq!(vec.get(0), Some(&10));
1537/// ```
1538impl<T> std::borrow::BorrowMut<[T]> for TruenoVec<T> {
1539 fn borrow_mut(&mut self) -> &mut [T] {
1540 self.as_slice_mut()
1541 }
1542}
1543
1544// ============================================================================
1545// Unit Tests (Tier 1: Sub-second feedback)
1546// ============================================================================
1547
1548#[cfg(test)]
1549#[path = "tests.rs"]
1550mod vec_tests;
1551
1552#[cfg(test)]
1553#[path = "property_tests.rs"]
1554mod vec_property_tests;