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