1use std::{
2 any::{type_name, TypeId},
3 ffi::c_void,
4 fmt::Debug,
5 iter::Iterator,
6 marker::PhantomData,
7 mem::MaybeUninit,
8 sync::OnceLock,
9};
10
11use bones_utils::{default, fxhash::FxHasher, parking_lot::RwLock, HashMap};
12
13use crate::{prelude::*, raw_fns::*};
14
15use super::ResizableAlloc;
16
17pub struct SchemaVec {
19 buffer: ResizableAlloc,
21 len: usize,
23 schema: &'static Schema,
25}
26
27impl std::fmt::Debug for SchemaVec {
28 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29 f.debug_struct("SchemaVec")
30 .field("buffer", &"ResizableAlloc")
31 .field("len", &self.len)
32 .field("schema", &self.schema)
33 .finish()
34 }
35}
36
37unsafe impl Sync for SchemaVec {}
39unsafe impl Send for SchemaVec {}
40
41impl SchemaVec {
42 pub fn new(schema: &'static Schema) -> Self {
44 Self {
45 buffer: ResizableAlloc::new(schema.layout()),
46 len: 0,
47 schema,
48 }
49 }
50
51 fn grow(&mut self) {
53 let cap = self.buffer.capacity();
54 if cap == 0 {
55 self.buffer.resize(1).unwrap();
56 } else {
57 self.buffer.resize(cap * 2).unwrap();
58 }
59 }
60
61 unsafe fn push_raw(&mut self, item: *mut c_void) {
66 if self.len == self.buffer.capacity() {
68 self.grow();
69 }
70
71 unsafe {
73 self.buffer
74 .unchecked_idx(self.len)
75 .copy_from_nonoverlapping(item, self.buffer.layout().size());
76 }
77
78 self.len += 1;
81 }
82
83 pub fn try_push<T: HasSchema>(&mut self, mut item: T) -> Result<(), SchemaMismatchError> {
87 if self.schema != T::schema() {
89 return Err(SchemaMismatchError);
90 }
91
92 unsafe {
93 self.push_raw(&mut item as *mut T as *mut c_void);
94 std::mem::forget(item);
95 }
96
97 Ok(())
98 }
99
100 #[inline]
104 #[track_caller]
105 pub fn push<T: HasSchema>(&mut self, item: T) {
106 self.try_push(item).unwrap()
107 }
108
109 pub fn try_push_box(&mut self, mut item: SchemaBox) -> Result<(), SchemaMismatchError> {
111 if self.schema != item.schema() {
113 return Err(SchemaMismatchError);
114 }
115
116 unsafe {
118 self.push_raw(item.as_mut().as_ptr());
119 }
120
121 item.forget();
123
124 Ok(())
125 }
126
127 #[track_caller]
129 #[inline]
130 pub fn push_box(&mut self, item: SchemaBox) {
131 self.try_push_box(item).unwrap()
132 }
133
134 pub fn pop_box(&mut self) -> Option<SchemaBox> {
136 if self.len == 0 {
137 None
138 } else {
139 unsafe { self.raw_pop() }.map(|ptr| unsafe {
140 let mut b = SchemaBox::uninitialized(self.schema);
141 b.as_mut()
142 .as_ptr()
143 .copy_from_nonoverlapping(ptr, self.buffer.layout().size());
144 b
145 })
146 }
147 }
148
149 pub fn try_pop<T: HasSchema>(&mut self) -> Result<Option<T>, SchemaMismatchError> {
153 if self.schema != T::schema() {
154 Err(SchemaMismatchError)
155 } else {
156 let ret = unsafe { self.raw_pop() }.map(|ptr| {
157 let mut data = MaybeUninit::<T>::uninit();
158 unsafe {
159 (data.as_mut_ptr() as *mut c_void)
160 .copy_from_nonoverlapping(ptr, self.buffer.layout().size());
161 data.assume_init()
162 }
163 });
164 Ok(ret)
165 }
166 }
167
168 unsafe fn raw_pop(&mut self) -> Option<*mut c_void> {
172 if self.len == 0 {
173 None
174 } else {
175 self.len -= 1;
177
178 Some(unsafe { self.buffer.unchecked_idx(self.len) })
180 }
181 }
182
183 #[inline]
187 #[track_caller]
188 pub fn pop<T: HasSchema>(&mut self) -> Option<T> {
189 self.try_pop().unwrap()
190 }
191
192 pub fn try_get<T: HasSchema>(&self, idx: usize) -> Result<Option<&T>, SchemaMismatchError> {
196 self.get_ref(idx).map(|x| x.try_cast()).transpose()
197 }
198
199 #[inline]
203 #[track_caller]
204 pub fn get<T: HasSchema>(&self, idx: usize) -> Option<&T> {
205 self.try_get(idx).unwrap()
206 }
207
208 pub fn get_ref(&self, idx: usize) -> Option<SchemaRef<'_>> {
210 if idx >= self.len {
211 None
212 } else {
213 let ptr = unsafe { self.buffer.unchecked_idx(idx) };
214 unsafe { Some(SchemaRef::from_ptr_schema(ptr, self.schema)) }
215 }
216 }
217
218 pub fn try_get_mut<T: HasSchema>(
222 &mut self,
223 idx: usize,
224 ) -> Result<Option<&mut T>, SchemaMismatchError> {
225 self.get_ref_mut(idx)
226 .map(|mut x| unsafe { x.try_cast_mut().map(|x| transmute_lifetime(x)) })
229 .transpose()
230 }
231
232 #[inline]
236 #[track_caller]
237 pub fn get_mut<T: HasSchema>(&mut self, idx: usize) -> Option<&mut T> {
238 self.try_get_mut(idx).unwrap()
239 }
240
241 pub fn get_ref_mut(&mut self, idx: usize) -> Option<SchemaRefMut<'_>> {
243 if idx >= self.len {
244 None
245 } else {
246 let ptr = unsafe { self.buffer.unchecked_idx(idx) };
247 unsafe { Some(SchemaRefMut::from_ptr_schema(ptr, self.schema)) }
248 }
249 }
250
251 #[inline]
253 pub fn len(&self) -> usize {
254 self.len
255 }
256
257 #[inline]
259 pub fn is_empty(&self) -> bool {
260 self.len() == 0
261 }
262
263 #[inline]
265 pub fn capacity(&self) -> usize {
266 self.buffer.capacity()
267 }
268
269 #[inline]
271 pub fn schema(&self) -> &'static Schema {
272 self.schema
273 }
274
275 pub fn iter(&self) -> SchemaVecIter {
277 SchemaVecIter { vec: self, idx: 0 }
278 }
279
280 pub fn iter_mut(&mut self) -> SchemaVecIterMut {
282 SchemaVecIterMut { vec: self, idx: 0 }
283 }
284
285 #[track_caller]
289 pub fn into_svec<T: HasSchema>(self) -> SVec<T> {
290 self.try_into_svec().unwrap()
291 }
292
293 pub fn try_into_svec<T: HasSchema>(self) -> Result<SVec<T>, SchemaMismatchError> {
297 if T::schema() == self.schema {
298 Ok(SVec {
299 vec: self,
300 _phantom: PhantomData,
301 })
302 } else {
303 Err(SchemaMismatchError)
304 }
305 }
306
307 #[track_caller]
311 pub fn hash(&self) -> u64 {
312 use std::hash::{Hash, Hasher};
313 let Some(hash_fn) = &self.schema.hash_fn else {
314 panic!("Schema doesn't specify a hash_fn");
315 };
316 let mut hasher = FxHasher::default();
317 for item_ptr in self.buffer.iter() {
318 let item_hash = unsafe { (hash_fn.get())(item_ptr) };
319 item_hash.hash(&mut hasher);
320 }
321 hasher.finish()
322 }
323
324 pub unsafe fn raw_hash(ptr: *const c_void) -> u64 {
328 let this = unsafe { &*(ptr as *const Self) };
329 this.hash()
330 }
331
332 pub unsafe fn raw_eq(a: *const c_void, b: *const c_void) -> bool {
336 let a = &*(a as *const Self);
337 let b = &*(b as *const Self);
338 a.eq(b)
339 }
340
341 pub fn remove(&mut self, index: usize) -> SchemaBox {
346 if index >= self.len {
347 panic!("index out of bounds");
348 }
349 let item = unsafe {
350 let ptr = self.buffer.unchecked_idx(index);
351 let mut boxed = SchemaBox::uninitialized(self.schema);
352 boxed
353 .as_mut()
354 .as_ptr()
355 .copy_from_nonoverlapping(ptr, self.schema.layout().size());
356
357 let to_move = self.len - index - 1;
359 if to_move > 0 {
360 std::ptr::copy(
361 self.buffer.unchecked_idx(index + 1),
362 self.buffer.unchecked_idx(index),
363 to_move * self.schema.layout().size(),
364 );
365 }
366
367 self.len -= 1;
368 boxed
369 };
370 item
371 }
372
373 pub fn clear(&mut self) {
375 while self.pop_box().is_some() {}
376 }
377
378 pub fn truncate(&mut self, len: usize) {
382 while self.len > len {
383 self.pop_box();
384 }
385 }
386}
387
388impl<T: HasSchema> FromIterator<T> for SVec<T> {
389 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
390 let mut this = Self::default();
391 for item in iter {
392 this.push(item);
393 }
394 this
395 }
396}
397
398impl<'a> IntoIterator for &'a SchemaVec {
399 type Item = SchemaRef<'a>;
400 type IntoIter = SchemaVecIter<'a>;
401 fn into_iter(self) -> Self::IntoIter {
402 self.iter()
403 }
404}
405impl<'a> IntoIterator for &'a mut SchemaVec {
406 type Item = SchemaRefMut<'a>;
407 type IntoIter = SchemaVecIterMut<'a>;
408 fn into_iter(self) -> Self::IntoIter {
409 self.iter_mut()
410 }
411}
412
413pub struct SchemaVecIter<'a> {
415 vec: &'a SchemaVec,
416 idx: usize,
417}
418
419impl<'a> Iterator for SchemaVecIter<'a> {
420 type Item = SchemaRef<'a>;
421 fn next(&mut self) -> Option<Self::Item> {
422 let item = self.vec.get_ref(self.idx);
423 if item.is_some() {
424 self.idx += 1;
425 }
426 item
427 }
428}
429
430pub struct SchemaVecIterMut<'a> {
432 vec: &'a mut SchemaVec,
433 idx: usize,
434}
435impl<'a> Iterator for SchemaVecIterMut<'a> {
436 type Item = SchemaRefMut<'a>;
437
438 fn next(&mut self) -> Option<Self::Item> {
439 let item = self
440 .vec
441 .get_ref_mut(self.idx)
442 .map(|x| unsafe { SchemaRefMut::from_ptr_schema(x.as_ptr(), x.schema()) });
445 if item.is_some() {
446 self.idx += 1;
447 }
448 item
449 }
450}
451
452impl Eq for SchemaVec {}
453impl PartialEq for SchemaVec {
454 #[track_caller]
455 fn eq(&self, other: &Self) -> bool {
456 if self.schema != other.schema {
457 panic!("Cannot compare two `SchemaVec`s with different schemas.");
458 }
459 let Some(eq_fn) = &self.schema.eq_fn else {
460 panic!("Schema doesn't have an eq_fn");
461 };
462
463 for i in 0..self.len {
464 unsafe {
465 let a = self.buffer.unchecked_idx(i);
466 let b = self.buffer.unchecked_idx(i);
467 if !(eq_fn.get())(a, b) {
468 return false;
469 }
470 }
471 }
472 true
473 }
474}
475
476impl Clone for SchemaVec {
477 fn clone(&self) -> Self {
478 let Some(clone_fn) = &self.schema.clone_fn else {
479 panic!("This type cannot be cloned");
480 };
481 let mut buffer_clone = ResizableAlloc::new(self.schema.layout());
482 buffer_clone.resize(self.len).unwrap();
483
484 for i in 0..self.len {
486 unsafe {
489 let item = self.buffer.unchecked_idx(i);
490 (clone_fn.get())(item, buffer_clone.unchecked_idx(i));
491 }
492 }
493
494 SchemaVec {
495 buffer: buffer_clone,
496 len: self.len,
497 schema: self.schema,
498 }
499 }
500}
501
502impl Drop for SchemaVec {
503 fn drop(&mut self) {
504 for _ in 0..self.len {
505 drop(self.pop_box().unwrap());
506 }
507 }
508}
509
510#[repr(transparent)]
517#[derive(Eq, PartialEq)]
518pub struct SVec<T: HasSchema> {
519 vec: SchemaVec,
520 _phantom: PhantomData<T>,
521}
522
523impl<T: HasSchema> SVec<T> {
524 pub fn new() -> Self {
526 Self {
527 vec: SchemaVec::new(T::schema()),
528 _phantom: PhantomData,
529 }
530 }
531
532 pub fn push(&mut self, mut item: T) {
534 unsafe {
536 self.vec.push_raw(&mut item as *mut T as *mut c_void);
537 }
538 std::mem::forget(item);
539 }
540
541 pub fn pop(&mut self) -> Option<T> {
543 unsafe {
544 self.vec.raw_pop().map(|ptr| {
545 let mut ret = MaybeUninit::<T>::uninit();
546 ret.as_mut_ptr().copy_from_nonoverlapping(ptr as *mut T, 1);
547 ret.assume_init()
548 })
549 }
550 }
551
552 pub fn get(&self, idx: usize) -> Option<&T> {
554 self.vec
556 .get_ref(idx)
557 .map(|x| unsafe { x.cast_into_unchecked() })
558 }
559
560 pub fn get_mut(&mut self, idx: usize) -> Option<&mut T> {
562 self.vec
564 .get_ref_mut(idx)
565 .map(|x| unsafe { x.cast_into_mut_unchecked() })
566 }
567
568 pub fn iter(&self) -> SVecIter<T> {
570 SVecIter {
571 vec: self,
572 idx: 0,
573 end: self.len() as isize - 1,
574 }
575 }
576
577 pub fn iter_mut(&mut self) -> SVecIterMut<T> {
579 SVecIterMut {
580 idx: 0,
581 end: self.len() as isize - 1,
582 vec: self,
583 }
584 }
585
586 #[inline]
588 pub fn len(&self) -> usize {
589 self.vec.len()
590 }
591
592 #[inline]
594 pub fn is_empty(&self) -> bool {
595 self.vec.is_empty()
596 }
597
598 #[inline]
600 pub fn capacity(&self) -> usize {
601 self.vec.capacity()
602 }
603
604 #[inline]
606 pub fn into_schema_vec(self) -> SchemaVec {
607 self.vec
608 }
609
610 pub fn hash(&self) -> u64 {
612 self.vec.hash()
613 }
614
615 pub fn remove(&mut self, index: usize) -> T {
620 let boxed = self.vec.remove(index);
621 unsafe { boxed.cast_into_unchecked() }
623 }
624
625 pub fn clear(&mut self) {
627 self.vec.clear();
628 }
629
630 pub fn truncate(&mut self, len: usize) {
634 self.vec.truncate(len);
635 }
636
637 pub fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
639 for item in iter {
640 self.push(item);
641 }
642 }
643
644 pub fn retain<F>(&mut self, mut f: F)
646 where
647 F: FnMut(&T) -> bool,
648 {
649 let mut i = 0;
650 while i < self.len() {
651 if !f(&self[i]) {
652 self.remove(i);
653 } else {
654 i += 1;
655 }
656 }
657 }
658
659 pub fn retain_mut<F>(&mut self, mut f: F)
661 where
662 F: FnMut(&mut T) -> bool,
663 {
664 let mut i = 0;
665 while i < self.len() {
666 if !f(self.get_mut(i).unwrap()) {
667 self.remove(i);
668 } else {
669 i += 1;
670 }
671 }
672 }
673
674 pub fn pop_if<F>(&mut self, f: F) -> Option<T>
676 where
677 F: FnOnce(&T) -> bool,
678 {
679 if let Some(last) = self.last() {
680 if f(last) {
681 self.pop()
682 } else {
683 None
684 }
685 } else {
686 None
687 }
688 }
689
690 pub fn first(&self) -> Option<&T> {
692 self.get(0)
693 }
694
695 pub fn first_mut(&mut self) -> Option<&mut T> {
697 self.get_mut(0)
698 }
699
700 pub fn last(&self) -> Option<&T> {
702 self.get(self.len().wrapping_sub(1))
703 }
704
705 pub fn last_mut(&mut self) -> Option<&mut T> {
707 let len = self.len();
708 self.get_mut(len.wrapping_sub(1))
709 }
710
711 pub fn reverse(&mut self) {
713 let mut i = 0;
714 let mut j = self.len().saturating_sub(1);
715 while i < j {
716 unsafe {
718 let ptr_i = self.get_mut(i).unwrap() as *mut T;
719 let ptr_j = self.get_mut(j).unwrap() as *mut T;
720 std::ptr::swap(ptr_i, ptr_j);
721 }
722 i += 1;
723 j -= 1;
724 }
725 }
726}
727
728pub struct SVecIntoIter<T: HasSchema> {
730 svec: SVec<T>,
731 index: usize,
732}
733
734impl<T: HasSchema + Debug> std::fmt::Debug for SVec<T> {
735 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
736 let mut l = f.debug_list();
737 for item in self.iter() {
738 l.entry(item);
739 }
740 l.finish()
741 }
742}
743
744impl<T: HasSchema> From<SVec<T>> for Vec<T> {
745 fn from(svec: SVec<T>) -> Self {
746 let mut vec = Vec::with_capacity(svec.len());
747 for item in svec {
748 vec.push(item);
749 }
750 vec
751 }
752}
753
754impl<T: HasSchema> From<Vec<T>> for SVec<T> {
755 fn from(vec: Vec<T>) -> Self {
756 let mut svec = SVec::new();
757 for item in vec {
758 svec.push(item);
759 }
760 svec
761 }
762}
763
764impl<T: HasSchema> IntoIterator for SVec<T> {
766 type Item = T;
767 type IntoIter = SVecIntoIter<T>;
768
769 fn into_iter(self) -> Self::IntoIter {
770 SVecIntoIter {
771 svec: self,
772 index: 0,
773 }
774 }
775}
776
777impl<T: HasSchema> Iterator for SVecIntoIter<T> {
778 type Item = T;
779
780 fn next(&mut self) -> Option<Self::Item> {
781 if self.index < self.svec.len() {
782 let item = self.svec.remove(self.index);
783 Some(item)
784 } else {
785 None
786 }
787 }
788
789 fn size_hint(&self) -> (usize, Option<usize>) {
790 let remaining = self.svec.len() - self.index;
791 (remaining, Some(remaining))
792 }
793}
794
795impl<T: HasSchema> Drop for SVecIntoIter<T> {
796 fn drop(&mut self) {
797 for _ in self.by_ref() {}
799 }
800}
801
802impl<T: HasSchema, const N: usize> From<[T; N]> for SVec<T> {
803 fn from(arr: [T; N]) -> Self {
804 arr.into_iter().collect()
805 }
806}
807
808impl<T: HasSchema> std::ops::Index<usize> for SVec<T> {
809 type Output = T;
810
811 #[track_caller]
812 fn index(&self, idx: usize) -> &Self::Output {
813 self.get(idx).unwrap()
814 }
815}
816
817impl<T: HasSchema> std::ops::IndexMut<usize> for SVec<T> {
818 #[track_caller]
819 fn index_mut(&mut self, idx: usize) -> &mut Self::Output {
820 self.get_mut(idx).unwrap()
821 }
822}
823
824impl<T: HasSchema> std::ops::Deref for SVec<T> {
825 type Target = [T];
826
827 fn deref(&self) -> &Self::Target {
828 unsafe { std::slice::from_raw_parts(self.vec.buffer.as_ptr() as *const T, self.len()) }
831 }
832}
833impl<T: HasSchema> std::ops::DerefMut for SVec<T> {
834 fn deref_mut(&mut self) -> &mut Self::Target {
835 unsafe { std::slice::from_raw_parts_mut(self.vec.buffer.as_ptr() as *mut T, self.len()) }
838 }
839}
840
841unsafe impl<T: HasSchema> HasSchema for SVec<T> {
842 fn schema() -> &'static Schema {
843 static S: OnceLock<RwLock<HashMap<TypeId, &'static Schema>>> = OnceLock::new();
844 let schema = {
845 S.get_or_init(default)
846 .read()
847 .get(&TypeId::of::<Self>())
848 .copied()
849 };
850 schema.unwrap_or_else(|| {
851 let schema = SCHEMA_REGISTRY.register(SchemaData {
852 name: type_name::<Self>().into(),
853 full_name: format!("{}::{}", module_path!(), type_name::<Self>()).into(),
854 kind: SchemaKind::Vec(T::schema()),
855 type_id: Some(TypeId::of::<Self>()),
856 clone_fn: Some(<Self as RawClone>::raw_clone_cb()),
857 drop_fn: Some(<Self as RawDrop>::raw_drop_cb()),
858 default_fn: Some(<Self as RawDefault>::raw_default_cb()),
859 hash_fn: Some(unsafe {
860 Unsafe::new(Box::leak(Box::new(|a| SchemaVec::raw_hash(a))))
861 }),
862 eq_fn: Some(unsafe {
863 Unsafe::new(Box::leak(Box::new(|a, b| SchemaVec::raw_eq(a, b))))
864 }),
865 type_data: Default::default(),
866 });
867
868 S.get_or_init(default)
869 .write()
870 .insert(TypeId::of::<Self>(), schema);
871
872 schema
873 })
874 }
875}
876
877impl<T: HasSchema> Default for SVec<T> {
878 fn default() -> Self {
879 Self {
880 vec: SchemaVec::new(T::schema()),
881 _phantom: Default::default(),
882 }
883 }
884}
885impl<T: HasSchema> Clone for SVec<T> {
886 fn clone(&self) -> Self {
887 Self {
888 vec: self.vec.clone(),
889 _phantom: self._phantom,
890 }
891 }
892}
893
894impl<'a, T: HasSchema> IntoIterator for &'a SVec<T> {
895 type Item = &'a T;
896 type IntoIter = SVecIter<'a, T>;
897 fn into_iter(self) -> Self::IntoIter {
898 self.iter()
899 }
900}
901impl<'a, T: HasSchema> IntoIterator for &'a mut SVec<T> {
902 type Item = &'a mut T;
903 type IntoIter = SVecIterMut<'a, T>;
904 fn into_iter(self) -> Self::IntoIter {
905 self.iter_mut()
906 }
907}
908
909pub struct SVecIter<'a, T: HasSchema> {
911 vec: &'a SVec<T>,
912 idx: usize,
913 end: isize,
914}
915impl<'a, T: HasSchema> Iterator for SVecIter<'a, T> {
916 type Item = &'a T;
917
918 fn next(&mut self) -> Option<Self::Item> {
919 if self.end < 0 {
920 return None;
921 }
922 let item = (self.idx <= self.end as usize).then(|| self.vec.get(self.idx).unwrap());
923 if item.is_some() {
924 self.idx += 1;
925 }
926 item
927 }
928}
929impl<'a, T: HasSchema> DoubleEndedIterator for SVecIter<'a, T> {
930 fn next_back(&mut self) -> Option<Self::Item> {
931 if self.end < 0 {
932 return None;
933 }
934 let item =
935 (self.end as usize >= self.idx).then(|| self.vec.get(self.end as usize).unwrap());
936 if item.is_some() {
937 self.end -= 1;
938 }
939 item
940 }
941}
942
943pub struct SVecIterMut<'a, T: HasSchema> {
945 vec: &'a mut SVec<T>,
946 idx: usize,
947 end: isize,
948}
949impl<'a, T: HasSchema> Iterator for SVecIterMut<'a, T> {
950 type Item = &'a mut T;
951
952 fn next(&mut self) -> Option<Self::Item> {
953 if self.end < 0 {
954 return None;
955 }
956 let item = (self.idx <= self.end as usize).then(|| self.vec.get_mut(self.idx).unwrap());
957 if item.is_some() {
958 self.idx += 1;
959 }
960 item.map(|x| unsafe { transmute_lifetime(x) })
963 }
964}
965impl<'a, T: HasSchema> DoubleEndedIterator for SVecIterMut<'a, T> {
966 fn next_back(&mut self) -> Option<Self::Item> {
967 if self.end < 0 {
968 return None;
969 }
970 let item =
971 (self.end as usize >= self.idx).then(|| self.vec.get_mut(self.end as usize).unwrap());
972 if item.is_some() {
973 self.end -= 1;
974 }
975 item.map(|x| unsafe { transmute_lifetime(x) })
978 }
979}
980
981unsafe fn transmute_lifetime<'b, T>(v: &mut T) -> &'b mut T {
986 std::mem::transmute(v)
987}
988
989#[cfg(test)]
990mod test {
991 use super::*;
992
993 #[test]
994 fn double_ended() {
995 let mut v = [1, 2, 3, 4, 5, 6].into_iter().collect::<SVec<_>>();
996
997 let mut iter = v.iter();
998 assert_eq!(iter.next_back(), Some(&6));
999 assert_eq!(iter.next_back(), Some(&5));
1000 assert_eq!(iter.next(), Some(&1));
1001 assert_eq!(iter.next(), Some(&2));
1002 assert_eq!(iter.next_back(), Some(&4));
1003 assert_eq!(iter.next(), Some(&3));
1004 assert_eq!(iter.next_back(), None);
1005 assert_eq!(iter.next(), None);
1006
1007 let mut iter = v.iter_mut();
1008 assert_eq!(iter.next_back(), Some(&mut 6));
1009 assert_eq!(iter.next_back(), Some(&mut 5));
1010 assert_eq!(iter.next(), Some(&mut 1));
1011 assert_eq!(iter.next(), Some(&mut 2));
1012 assert_eq!(iter.next_back(), Some(&mut 4));
1013 assert_eq!(iter.next(), Some(&mut 3));
1014 assert_eq!(iter.next_back(), None);
1015 assert_eq!(iter.next(), None);
1016
1017 let v = [].into_iter().collect::<SVec<u8>>();
1018 let mut iter = v.iter();
1019 assert_eq!(iter.next(), None);
1020 assert_eq!(iter.next(), None);
1021 assert_eq!(iter.next_back(), None);
1022 let mut iter = v.iter();
1023 assert_eq!(iter.next_back(), None);
1024 assert_eq!(iter.next(), None);
1025 }
1026
1027 #[test]
1028 fn test_vec_and_svec_conversions() {
1029 let vec = vec![1, 2, 3, 4, 5];
1031 let svec: SVec<i32> = vec.clone().into();
1032 assert_eq!(svec.len(), 5);
1033 let vec_from_svec: Vec<i32> = svec.into();
1035 assert_eq!(vec, vec_from_svec);
1036 let svec_direct: SVec<i32> = [11, 12, 13].into();
1038 assert_eq!(svec_direct.len(), 3);
1039 let vec_from_array_svec: Vec<i32> = svec_direct.into();
1041 assert_eq!(vec_from_array_svec, vec![11, 12, 13]);
1042 }
1043
1044 #[test]
1045 fn test_remove() {
1046 let mut svec: SVec<i32> = vec![10, 20, 30, 40, 50].into();
1047
1048 let removed = svec.remove(2);
1050 assert_eq!(removed, 30);
1051 assert_eq!(svec.len(), 4);
1052 assert_eq!(svec[0], 10);
1053
1054 let removed = svec.remove(0);
1056 assert_eq!(removed, 10);
1057 assert_eq!(svec.len(), 3);
1058 assert_eq!(svec[0], 20);
1059
1060 let removed = svec.remove(2);
1062 assert_eq!(removed, 50);
1063 assert_eq!(svec.len(), 2);
1064 assert_eq!(svec[1], 40);
1065
1066 let removed = svec.remove(1);
1068 assert_eq!(removed, 40);
1069 assert_eq!(svec.len(), 1);
1070 assert_eq!(svec[0], 20);
1071
1072 let removed = svec.remove(0);
1074 assert_eq!(removed, 20);
1075 assert_eq!(svec.len(), 0);
1076 }
1077
1078 #[test]
1079 fn test_svec_operations() {
1080 let mut vec: SVec<i32> = SVec::new();
1081
1082 vec.push(1);
1084 vec.push(2);
1085 vec.push(3);
1086 assert_eq!(vec.len(), 3);
1087
1088 assert_eq!(vec.get(1), Some(&2));
1090 assert_eq!(vec.get(3), None);
1091
1092 let removed = vec.remove(2);
1094 assert_eq!(removed, 3);
1095 assert_eq!(vec.len(), 2);
1096
1097 let sum: i32 = vec.iter().copied().sum();
1099 assert_eq!(sum, 3); vec.extend(vec![5, 6]);
1103 assert_eq!(vec.len(), 4);
1104 assert_eq!(vec.get(2), Some(&5));
1105 assert_eq!(vec.get(3), Some(&6));
1106
1107 vec.retain(|&x| x % 2 == 0);
1109 assert_eq!(vec.len(), 2);
1110 assert_eq!(vec[0], 2);
1111 assert_eq!(vec[1], 6);
1112
1113 vec.retain_mut(|x| {
1115 *x *= 2;
1116 true
1117 });
1118 assert_eq!(vec.len(), 2);
1119 assert_eq!(vec[0], 4);
1120 assert_eq!(vec[1], 12);
1121
1122 vec.truncate(1);
1124 assert_eq!(vec.len(), 1);
1125 assert_eq!(vec[0], 4);
1126 assert_eq!(vec.get(1), None);
1127
1128 vec.extend(vec![7, 9, 11]);
1130
1131 assert_eq!(vec.first(), Some(&4));
1133 if let Some(first) = vec.first_mut() {
1134 *first = 1;
1135 }
1136 assert_eq!(vec[0], 1);
1137
1138 assert_eq!(vec.last(), Some(&11));
1140 if let Some(last) = vec.last_mut() {
1141 *last = 15;
1142 }
1143 assert_eq!(vec[3], 15);
1144
1145 assert_eq!(vec.pop_if(|&x| x > 10), Some(15));
1147 assert_eq!(vec.len(), 3);
1148 assert_eq!(vec.pop_if(|&x| x < 0), None);
1149 assert_eq!(vec.len(), 3);
1150
1151 vec.clear();
1153 assert_eq!(vec.len(), 0);
1154 assert!(vec.is_empty());
1155
1156 assert_eq!(vec.pop(), None);
1158
1159 let original_vec = vec![1, 2, 3, 4, 5];
1161 let svec: SVec<i32> = original_vec.clone().into();
1162 let vec_from_svec: Vec<i32> = svec.into();
1163 assert_eq!(original_vec, vec_from_svec);
1164
1165 let mut reversed_vec = original_vec.clone();
1167 reversed_vec.reverse();
1168 assert_eq!(reversed_vec, vec![5, 4, 3, 2, 1]);
1169 }
1170
1171 #[test]
1172 fn miri_error_001() {
1173 let mut vec: SVec<i32> = SVec::new();
1174 vec.push(10);
1175 vec.pop();
1176 }
1177}