1#![no_std]
30#![deny(missing_docs)]
31#![feature(min_const_generics)]
32
33pub struct MaxSizeVec<T, const SIZE: usize> {
38 data: [core::mem::ManuallyDrop<T>; SIZE],
39 length: usize
40}
41
42pub struct MaxSizeVecIter<T, const SIZE: usize> {
44 data: [core::mem::ManuallyDrop<T>; SIZE],
45 length: usize,
46 offset: usize
47}
48
49impl<T, const SIZE: usize> core::iter::Iterator for MaxSizeVecIter<T, {SIZE}> {
50 type Item = T;
51 fn next(&mut self) -> Option<T> {
52 if self.offset >= self.length {
53 None
54 } else {
55 self.offset += 1;
56 Some(unsafe {
58 core::ptr::read((self.data.as_ptr() as *const T).offset_unsigned(self.offset - 1))
59 })
60 }
61 }
62}
63
64pub struct Drain<'a, T, const SIZE: usize> {
66 vector: &'a mut MaxSizeVec<T, {SIZE}>,
67 original_start: usize,
68 start: usize,
69 end: usize
70}
71
72impl<'a, T, const SIZE: usize> core::iter::Iterator for Drain<'a, T, {SIZE}> {
73 type Item = T;
74 fn next(&mut self) -> Option<T> {
75 if self.start >= self.end {
76 None
77 } else {
78 self.start += 1;
79 Some(unsafe {
83 core::ptr::read(self.vector.as_ptr().offset(self.start as isize - 1))
84 })
85 }
86 }
87}
88
89impl<'a, T, const SIZE: usize> core::ops::Drop for Drain<'a, T, {SIZE}> {
90 fn drop(&mut self) {
91 let amount_to_remove = self.end - self.original_start;
92 unsafe {
93 for x in self.start..self.end {
95 core::ptr::drop_in_place(
96 self.vector.as_mut_ptr().offset_unsigned(x)
97 );
98 }
99 core::ptr::copy(
105 self.vector.as_ptr().offset_unsigned(self.end),
106 self.vector.as_mut_ptr().offset_unsigned(self.original_start),
107 self.vector.length - self.end
108 );
109 }
110 self.vector.length -= amount_to_remove;
111 }
112}
113
114trait OffsetUnsigned {
115 unsafe fn offset_unsigned(&self, offset: usize) -> Self;
116}
117
118impl<T> OffsetUnsigned for *const T {
119 unsafe fn offset_unsigned(&self, offset: usize) -> *const T {
120 self.offset(offset as isize)
121 }
122}
123
124impl<T> OffsetUnsigned for *mut T {
125 unsafe fn offset_unsigned(&self, offset: usize) -> *mut T {
126 self.offset(offset as isize)
127 }
128}
129
130impl<T, const SIZE: usize> Drop for MaxSizeVec<T, {SIZE}> {
131 fn drop(&mut self) {
132 for x in 0..self.length {
134 unsafe {
135 core::mem::ManuallyDrop::drop(&mut self.data[x]);
136 }
137 }
138 }
139}
140
141impl<T: Clone, const SIZE: usize> Clone for MaxSizeVec<T, {SIZE}> {
142 fn clone(&self) -> MaxSizeVec<T, {SIZE}> {
143 MaxSizeVec {
144 data: self.data.clone(),
145 length: self.length
146 }
147 }
148}
149
150impl<T: PartialEq, const SIZE: usize> PartialEq<&[T]> for MaxSizeVec<T, {SIZE}> {
151 fn eq(&self, other: &&[T]) -> bool {
152 self.as_slice() == *other
153 }
154}
155
156impl<T: PartialEq, const SIZE: usize, const OTHER: usize> PartialEq<MaxSizeVec<T, {OTHER}>> for MaxSizeVec<T, {SIZE}> {
157 fn eq(&self, other: &MaxSizeVec<T, {OTHER}>) -> bool {
158 self.as_slice() == other.as_slice()
159 }
160}
161
162impl<T: PartialEq, const SIZE: usize, const OTHER: usize> PartialEq<[T; {OTHER}]> for MaxSizeVec<T, {SIZE}> {
163 fn eq(&self, other: &[T; {OTHER}]) -> bool {
164 self.as_slice() == other
165 }
166}
167
168impl<T: PartialEq, const SIZE: usize, const OTHER: usize> PartialEq<&[T; {OTHER}]> for MaxSizeVec<T, {SIZE}> {
169 fn eq(&self, other: &&[T; {OTHER}]) -> bool {
170 self.as_slice() == *other
171 }
172}
173
174impl<T: core::fmt::Debug, const SIZE: usize> core::fmt::Debug for MaxSizeVec<T, {SIZE}> {
175 fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
176 unsafe {
178 core::mem::transmute::<&[core::mem::ManuallyDrop<T>], &[T]>(&self.data[..self.length])
179 }.fmt(fmt)
180 }
181}
182
183impl<T, const SIZE: usize> MaxSizeVec<T, {SIZE}> {
184 pub fn new() -> MaxSizeVec<T, {SIZE}> {
186 MaxSizeVec {
188 data: unsafe {
189 core::mem::MaybeUninit::zeroed().assume_init()
190 },
191 length: 0usize
192 }
193 }
194
195 pub fn push(&mut self, val: T) {
197 if self.length == self.data.len() {
198 panic!("Attempt to push when there's no room left in a max size vector!");
199 }
200 self.data[self.length] = core::mem::ManuallyDrop::new(val);
201 self.length += 1;
202 }
203
204 pub fn pop(&mut self) {
206 if self.length == 0 {
207 panic!("Attempt to pop a max-size vector with underflow!");
208 }
209 unsafe {
211 core::mem::ManuallyDrop::drop(&mut self.data[self.length - 1]);
212 }
213 self.length -= 1;
214 }
215
216 pub fn len(&self) -> usize {
218 self.length
219 }
220
221 pub fn drain<'a, R: core::ops::RangeBounds<usize>>(&'a mut self, range: R) -> Drain<'a, T, {SIZE}> {
223 use core::ops::Bound;
224 let start = match range.start_bound() {
225 Bound::Unbounded => 0usize,
226 Bound::Included(x) => {
227 let x = *x;
228 if x >= self.len() {
229 panic!("Range out of bounds!")
230 } else {
231 x
232 }
233 },
234 _ => unreachable!()
235 };
236
237 let end = match range.end_bound() {
238 Bound::Unbounded => self.len(),
239 Bound::Included(x) => if *x + 1 > self.len() {
240 panic!("Range out of bounds!")
241 } else {
242 *x + 1
243 },
244 Bound::Excluded(x) => {
245 let x = *x;
246 if x > self.len() {
247 panic!("Range out of bounds!")
248 } else {
249 x
250 }
251 },
252 };
253
254 Drain {
255 start,
256 end,
257 vector: self,
258 original_start: start
259 }
260 }
261
262 pub fn append<const OTHER_SIZE: usize>(&mut self, other: &mut MaxSizeVec<T, {OTHER_SIZE}>) {
264 if self.length + other.length > self.data.len() {
266 panic!("Attempt to append beyond the bounds of a max-size vector!");
267 }
268 unsafe {
271 core::ptr::copy_nonoverlapping(
272 other.as_ptr(),
273 self.as_mut_ptr().offset_unsigned(self.length),
274 other.len()
275 )
276 }
277 self.length += other.len();
279 *other = MaxSizeVec::new();
281 }
282
283 pub fn as_mut_ptr(&mut self) -> *mut T {
285 self.data.as_mut_ptr() as *mut T
286 }
287
288 pub fn as_mut_slice(&mut self) -> &mut [T] {
290 unsafe {
292 core::mem::transmute::<&mut [core::mem::ManuallyDrop<T>], &mut [T]>(&mut self.data[..self.length])
293 }
294 }
295
296 pub fn as_ptr(&self) -> *const T {
298 self.data.as_ptr() as *const T
299 }
300
301 pub fn as_slice(&self) -> &[T] {
303 unsafe {
305 core::mem::transmute::<&[core::mem::ManuallyDrop<T>], &[T]>(&self.data[..self.length])
306 }
307 }
308
309 pub fn capacity(&self) -> usize {
311 self.data.len()
312 }
313
314 pub fn clear(&mut self) {
316 *self = MaxSizeVec::new();
317 }
318
319 pub fn insert(&mut self, index: usize, element: T) {
321 if self.length + 1 >= self.data.len() {
323 panic!("Attempt to insert into a max-sized vector with overflow!");
324 }
325 if index > self.length {
326 panic!("Index out of bounds during insertion into max-sized vector!");
327 }
328 if index == self.length {
329 self.push(element);
330 } else {
331 unsafe {
332 self.length += 1;
334 core::ptr::copy(
336 self.as_ptr().offset_unsigned(index),
337 self.as_mut_ptr().offset_unsigned(index + 1),
338 self.length - index
339 );
340 *self.as_mut_ptr().offset_unsigned(index) = element;
342 }
343 }
344 }
345
346 pub fn truncate(&mut self, size: usize) {
348 if size > self.length {
349 panic!("Attempt to truncate a max-sized vector to larger length!");
350 }
351 if size != self.length {
352 for x in 0..self.length - size - 1 {
353 unsafe {
355 let ptr: *mut core::mem::ManuallyDrop<T> = self.data.as_mut_ptr().offset_unsigned(
356 self.length - x
357 );
358 core::mem::ManuallyDrop::drop(core::mem::transmute::<_, &mut core::mem::ManuallyDrop<T>>(ptr))
359 }
360 }
361 self.length = size;
362 }
363 }
364
365 pub fn resize_with(&mut self, size: usize, mut f: impl FnMut() -> T) {
368 if size >= self.data.len() {
369 panic!("The size passed to the resize function of a max-sized vector was larger than the vector's bounds!");
370 }
371 if size >= self.length {
372 for _ in 0..size - self.length {
373 self.push(f());
374 }
375 } else {
376 self.truncate(size);
377 }
378 }
379
380 pub fn retain(&mut self, mut predicate: impl FnMut(&T) -> bool) {
382 let mut current_length = 0usize;
383 for x in 0..self.length {
385 if predicate(&self[x]) {
386 unsafe {
388 core::ptr::copy(self.as_ptr().offset_unsigned(x), self.as_mut_ptr().offset_unsigned(current_length), 1usize)
389 };
390 current_length += 1;
391 } else {
392 unsafe {
394 core::ptr::drop_in_place(self.as_mut_ptr().offset_unsigned(x))
395 }
396 }
397 }
398 self.length = current_length;
400 }
401
402 pub fn remove(&mut self, index: usize) {
404 if index >= self.length {
405 panic!("Index for removal out of bounds for max-sized vector!");
406 }
407 unsafe {
408 core::ptr::drop_in_place(self.as_mut_ptr().offset_unsigned(index));
410 }
411 if index != self.length - 1 {
412 unsafe {
413 core::ptr::copy(
415 self.as_ptr().offset_unsigned(index + 1),
416 self.as_mut_ptr().offset_unsigned(index),
417 self.length - index - 1
418 );
419 }
420 }
421 self.length -= 1;
424 }
425
426 pub fn swap_remove(&mut self, index: usize) {
429 if index >= self.length {
430 panic!("Index out of bounds for swap remove operation on max-sized vector!");
431 }
432 if index == self.length - 1 {
433 self.pop();
434 } else {
435 unsafe {
437 core::ptr::swap_nonoverlapping(
438 self.as_mut_ptr().offset_unsigned(index), self.as_mut_ptr().offset_unsigned(self.length - 1), 1usize
439 );
440 }
441 self.pop();
442 }
443 }
444
445 pub fn is_empty(&self) -> bool {
447 self.length == 0
448 }
449}
450
451impl<T, const SIZE: usize> core::ops::Deref for MaxSizeVec<T, {SIZE}> {
452 type Target = [T];
453 fn deref(&self) -> &Self::Target {
454 self.as_slice()
455 }
456}
457
458impl<T, const SIZE: usize> core::ops::DerefMut for MaxSizeVec<T, {SIZE}> {
459 fn deref_mut(&mut self) -> &mut [T] {
460 self.as_mut_slice()
461 }
462}
463
464impl<T: Clone, const SIZE: usize> MaxSizeVec<T, {SIZE}> {
465 pub fn resize(&mut self, size: usize, value: T) {
467 if size >= self.data.len() {
468 panic!("The size passed to the resize function of a max-sized vector was larger than the vector's bounds!");
469 }
470 if size >= self.length {
471 for _ in 0..size - self.length {
472 self.push(value.clone());
473 }
474 } else {
475 self.truncate(size);
476 }
477 }
478
479 pub fn extend_from_slice(&mut self, other: &[T]) {
481 if self.len() + other.len() >= self.data.len() {
482 panic!("Attempt to extend by a slice beyond the bounds of a max-sized vector!");
483 }
484 for (n, x) in other.iter().cloned().enumerate() {
485 unsafe {
488 *self.data.as_mut_ptr().offset_unsigned(self.length + n) = core::mem::ManuallyDrop::new(x);
489 }
490 }
491 }
492}
493
494impl<T, const SIZE: usize> core::iter::Extend<T> for MaxSizeVec<T, {SIZE}> {
495 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
496 let mut iter = iter.into_iter();
497 let mut x = iter.next();
498 while x.is_some() {
499 if self.length >= self.data.len() {
500 panic!("Attempt to extend beyond the bounds of a max-sized vector!");
501 }
502 self.data[self.length] = core::mem::ManuallyDrop::new(x.unwrap());
503 self.length += 1;
504 x = iter.next();
505 }
506 }
507}
508
509impl<'a, T: 'a + Copy, const SIZE: usize> core::iter::Extend<&'a T> for MaxSizeVec<T, {SIZE}> {
510 fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
511 let mut iter = iter.into_iter();
512 let mut x = iter.next();
513 while x.is_some() {
514 if self.length >= self.data.len() {
515 panic!("Attempt to extend beyond the bounds of a max-sized vector!");
516 }
517 self.data[self.length] = core::mem::ManuallyDrop::new(x.unwrap().clone());
518 self.length += 1;
519 x = iter.next();
520 }
521 }
522}
523
524impl<T, const SIZE: usize> core::ops::Index<usize> for MaxSizeVec<T, {SIZE}> {
525 type Output = T;
526 fn index(&self, index: usize) -> &T {
527 if index >= self.length {
528 panic!("Index {} out of bounds of fixed size vec!", index);
529 }
530 unsafe {
533 core::mem::transmute(self.data.index(index))
534 }
535 }
536}
537
538impl<T, const SIZE: usize> core::ops::IndexMut<usize> for MaxSizeVec<T, {SIZE}> {
539 fn index_mut(&mut self, index: usize) -> &mut T {
540 if index >= self.length {
541 panic!("Index {} out of bounds of fixed size vec!", index);
542 }
543 unsafe {
546 core::mem::transmute(self.data.index_mut(index))
547 }
548 }
549}
550
551impl<T, const SIZE: usize> core::convert::AsMut<[T]> for MaxSizeVec<T, {SIZE}> {
552 fn as_mut(&mut self) -> &mut [T] {
553 self.as_mut_slice()
554 }
555}
556
557impl<T, const SIZE: usize> core::convert::AsMut<MaxSizeVec<T, {SIZE}>> for MaxSizeVec<T, {SIZE}> {
558 fn as_mut(&mut self) -> &mut Self {
559 self
560 }
561}
562
563impl<T, const SIZE: usize> core::convert::AsRef<[T]> for MaxSizeVec<T, {SIZE}> {
564 fn as_ref(&self) -> &[T] {
565 self.as_slice()
566 }
567}
568
569impl<T, const SIZE: usize> core::convert::AsRef<MaxSizeVec<T, {SIZE}>> for MaxSizeVec<T, {SIZE}> {
570 fn as_ref(&self) -> &Self {
571 self
572 }
573}
574
575impl<T, const SIZE: usize> core::borrow::Borrow<[T]> for MaxSizeVec<T, {SIZE}> {
576 fn borrow(&self) -> &[T] {
577 self.as_slice()
578 }
579}
580
581impl<T, const SIZE: usize> core::borrow::BorrowMut<[T]> for MaxSizeVec<T, {SIZE}> {
582 fn borrow_mut(&mut self) -> &mut [T] {
583 self.as_mut_slice()
584 }
585}
586
587impl<T: Eq, const SIZE: usize> Eq for MaxSizeVec<T, {SIZE}> {}
588
589impl<'a, T: Clone, const SIZE: usize> From<&'a [T]> for MaxSizeVec<T, {SIZE}> {
590 fn from(x: &[T]) -> Self {
591 let mut v = MaxSizeVec::new();
592 v.extend(x.iter().cloned());
593 v
594 }
595}
596
597impl<'a, T: Clone, const SIZE: usize> From<&'a mut [T]> for MaxSizeVec<T, {SIZE}> {
598 fn from(x: &mut [T]) -> Self {
599 let mut v = MaxSizeVec::new();
600 v.extend(x.iter().cloned());
601 v
602 }
603}
604
605impl<'a, const SIZE: usize> From<&'a str> for MaxSizeVec<u8, {SIZE}> {
606 fn from(x: &str) -> Self {
607 let mut v = MaxSizeVec::new();
608 v.extend(x.as_bytes().iter().cloned());
609 v
610 }
611}
612
613impl<T, const SIZE: usize> core::iter::FromIterator<T> for MaxSizeVec<T, {SIZE}> {
614 fn from_iter<I: IntoIterator<Item = T>>(x: I) -> Self {
615 let mut v = MaxSizeVec::new();
616 v.extend(x);
617 v
618 }
619}
620
621impl<T, const SIZE: usize> core::iter::IntoIterator for MaxSizeVec<T, {SIZE}> {
622 type Item = T;
623 type IntoIter = MaxSizeVecIter<T, {SIZE}>;
624 fn into_iter(self) -> MaxSizeVecIter<T, {SIZE}> {
625 MaxSizeVecIter {
629 offset: 0usize,
630 length: self.length,
631 data: unsafe {
632 core::mem::transmute_copy(&self.data)
633 }
634 }
635 }
636}
637
638impl<'a, T, const SIZE: usize> core::iter::IntoIterator for &'a MaxSizeVec<T, {SIZE}> {
639 type Item = &'a T;
640 type IntoIter = core::slice::Iter<'a, T>;
641 fn into_iter(self) -> core::slice::Iter<'a, T> {
642 self.iter()
643 }
644}
645
646impl<T: PartialOrd, const SIZE: usize> PartialOrd for MaxSizeVec<T, {SIZE}> {
647 fn partial_cmp(&self, other: &MaxSizeVec<T, {SIZE}>) -> Option<core::cmp::Ordering> {
648 PartialOrd::partial_cmp(self.as_slice(), other.as_slice())
649 }
650}
651
652impl<T: Ord, const SIZE: usize> Ord for MaxSizeVec<T, {SIZE}> {
653 fn cmp(&self, other: &MaxSizeVec<T, {SIZE}>) -> core::cmp::Ordering {
654 Ord::cmp(self.as_slice(), other.as_slice())
655 }
656}
657
658#[test]
659fn dropping_order() {
660 use core::sync::atomic::*;
661
662 #[derive(Clone, Debug)]
663 struct DropTest;
664
665 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0usize);
666 impl Drop for DropTest {
667 fn drop(&mut self) {
668 DROP_COUNT.fetch_add(1usize, Ordering::SeqCst);
669 }
670 }
671
672 let mut x: MaxSizeVec<DropTest, 1024> = MaxSizeVec::new();
673 x.extend((1..=1024).map(|_| DropTest));
674 x.resize(512, DropTest);
675 x.swap_remove(0usize);
676 x.pop();
677
678 let mut collection: MaxSizeVec<DropTest, 1024> = MaxSizeVec::new();
679 for v in x.drain(..) {
680 collection.push(v);
681 }
682 x.append(&mut collection);
683 x.drain(..);
684
685 assert_eq!(x.len(), 0);
686 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 1534);
687}
688
689#[test]
690fn operational_correctness() {
691 let mut x: MaxSizeVec<usize, 1024> = MaxSizeVec::new();
692
693 x.push(0usize);
694 x.swap_remove(0usize);
695 x.extend(5..10usize);
696 x.pop();
697 x.retain(|x| *x > 6);
698 x.drain(0..1);
699 x.drain(..1);
700 x.push(2);
701 x.insert(1usize, 1usize);
702 x.insert(0usize, 1usize);
703 x.remove(0usize);
704
705 assert_eq!(x, &[2, 1]);
706}