1use crate::inline_array::InlineArray;
10use core::borrow::{Borrow, BorrowMut};
11use core::cmp::Ordering;
12use core::fmt::{Debug, Error, Formatter};
13use core::hash::{Hash, Hasher};
14use core::iter::FromIterator;
15use core::mem::{replace, MaybeUninit};
16use core::ops::{Deref, DerefMut, Index, IndexMut};
17use core::ptr;
18use core::slice::{
19 from_raw_parts, from_raw_parts_mut, Iter as SliceIter, IterMut as SliceIterMut, SliceIndex,
20};
21
22#[cfg(feature = "std")]
23use std::io;
24
25mod iter;
26pub use self::iter::{Drain, Iter};
27
28#[cfg(feature = "refpool")]
29mod refpool;
30
31pub struct Chunk<A, const N: usize> {
94 left: usize,
95 right: usize,
96 data: MaybeUninit<[A; N]>,
97}
98
99impl<A, const N: usize> Drop for Chunk<A, N> {
100 fn drop(&mut self) {
101 unsafe { ptr::drop_in_place(self.as_mut_slice()) }
102 }
103}
104
105impl<A, const N: usize> Clone for Chunk<A, N>
106where
107 A: Clone,
108{
109 fn clone(&self) -> Self {
110 let mut out = Self::new();
111 out.left = self.left;
112 out.right = self.left;
113 for index in self.left..self.right {
114 unsafe { Chunk::force_write(index, (*self.ptr(index)).clone(), &mut out) }
115 out.right = index + 1;
119 }
120 out
121 }
122}
123
124impl<A, const N: usize> Chunk<A, N> {
125 pub const CAPACITY: usize = N;
127
128 pub fn new() -> Self {
130 Self {
131 left: 0,
132 right: 0,
133 data: MaybeUninit::uninit(),
134 }
135 }
136
137 pub fn unit(value: A) -> Self {
139 assert!(Self::CAPACITY >= 1);
140 let mut chunk = Self {
141 left: 0,
142 right: 1,
143 data: MaybeUninit::uninit(),
144 };
145 unsafe {
146 Chunk::force_write(0, value, &mut chunk);
147 }
148 chunk
149 }
150
151 pub fn pair(left: A, right: A) -> Self {
153 assert!(Self::CAPACITY >= 2);
154 let mut chunk = Self {
155 left: 0,
156 right: 2,
157 data: MaybeUninit::uninit(),
158 };
159 unsafe {
160 Chunk::force_write(0, left, &mut chunk);
161 Chunk::force_write(1, right, &mut chunk);
162 }
163 chunk
164 }
165
166 pub fn drain_from(other: &mut Self) -> Self {
171 let other_len = other.len();
172 Self::from_front(other, other_len)
173 }
174
175 pub fn collect_from<I>(iter: &mut I, mut count: usize) -> Self
182 where
183 I: Iterator<Item = A>,
184 {
185 let mut chunk = Self::new();
186 while count > 0 {
187 count -= 1;
188 chunk.push_back(
189 iter.next()
190 .expect("Chunk::collect_from: underfull iterator"),
191 );
192 }
193 chunk
194 }
195
196 pub fn from_front(other: &mut Self, count: usize) -> Self {
201 let other_len = other.len();
202 debug_assert!(count <= other_len);
203 let mut chunk = Self::new();
204 unsafe { Chunk::force_copy_to(other.left, 0, count, other, &mut chunk) };
205 chunk.right = count;
206 other.left += count;
207 chunk
208 }
209
210 pub fn from_back(other: &mut Self, count: usize) -> Self {
215 let other_len = other.len();
216 debug_assert!(count <= other_len);
217 let mut chunk = Self::new();
218 unsafe { Chunk::force_copy_to(other.right - count, 0, count, other, &mut chunk) };
219 chunk.right = count;
220 other.right -= count;
221 chunk
222 }
223
224 #[inline]
226 pub fn len(&self) -> usize {
227 self.right - self.left
228 }
229
230 #[inline]
232 pub fn is_empty(&self) -> bool {
233 self.left == self.right
234 }
235
236 #[inline]
238 pub fn is_full(&self) -> bool {
239 self.left == 0 && self.right == Self::CAPACITY
240 }
241
242 #[inline]
243 unsafe fn ptr(&self, index: usize) -> *const A {
244 unsafe { (&self.data as *const _ as *const A).add(index) }
245 }
246
247 #[inline]
249 unsafe fn mut_ptr(&mut self, index: usize) -> *mut A {
250 unsafe { (&mut self.data as *mut _ as *mut A).add(index) }
251 }
252
253 #[inline]
255 unsafe fn force_read(index: usize, chunk: &mut Self) -> A {
256 unsafe { chunk.ptr(index).read() }
257 }
258
259 #[inline]
262 unsafe fn force_write(index: usize, value: A, chunk: &mut Self) {
263 unsafe { chunk.mut_ptr(index).write(value) }
264 }
265
266 #[inline]
268 unsafe fn force_copy(from: usize, to: usize, count: usize, chunk: &mut Self) {
269 if count > 0 {
270 let data = &mut chunk.data as *mut _ as *mut A;
271 unsafe {
272 let from = data.add(from);
273 let to = data.add(to);
274 ptr::copy(from, to, count)
275 }
276 }
277 }
278
279 #[inline]
294 unsafe fn write_from_iter<I>(mut write_index: usize, iter: I, chunk: &mut Self)
295 where
296 I: ExactSizeIterator<Item = A>,
297 {
298 let left = replace(&mut chunk.left, 0);
306 let right = replace(&mut chunk.right, 0);
307 let len = iter.len();
308 let expected_end = write_index + len;
309 for value in iter.take(len) {
310 unsafe {
311 Chunk::force_write(write_index, value, chunk);
312 }
313 write_index += 1;
314 }
315 assert_eq!(
317 expected_end, write_index,
318 "ExactSizeIterator yielded fewer values than advertised",
319 );
320 chunk.left = left;
321 chunk.right = right;
322 }
323
324 #[inline]
326 unsafe fn force_copy_to(
327 from: usize,
328 to: usize,
329 count: usize,
330 chunk: &mut Self,
331 other: &mut Self,
332 ) {
333 if count > 0 {
334 unsafe { ptr::copy_nonoverlapping(chunk.ptr(from), other.mut_ptr(to), count) }
335 }
336 }
337
338 pub fn push_front(&mut self, value: A) {
344 if self.is_full() {
345 panic!("Chunk::push_front: can't push to full chunk");
346 }
347 if self.is_empty() {
348 self.left = N;
349 self.right = N;
350 } else if self.left == 0 {
351 self.left = N - self.right;
352 unsafe { Chunk::force_copy(0, self.left, self.right, self) };
353 self.right = N;
354 }
355 self.left -= 1;
356 unsafe { Chunk::force_write(self.left, value, self) }
357 }
358
359 pub fn push_back(&mut self, value: A) {
365 if self.is_full() {
366 panic!("Chunk::push_back: can't push to full chunk");
367 }
368 if self.is_empty() {
369 self.left = 0;
370 self.right = 0;
371 } else if self.right == N {
372 unsafe { Chunk::force_copy(self.left, 0, self.len(), self) };
373 self.right = N - self.left;
374 self.left = 0;
375 }
376 unsafe { Chunk::force_write(self.right, value, self) }
377 self.right += 1;
378 }
379
380 pub fn pop_front(&mut self) -> A {
386 if self.is_empty() {
387 panic!("Chunk::pop_front: can't pop from empty chunk");
388 } else {
389 let value = unsafe { Chunk::force_read(self.left, self) };
390 self.left += 1;
391 value
392 }
393 }
394
395 pub fn pop_back(&mut self) -> A {
401 if self.is_empty() {
402 panic!("Chunk::pop_back: can't pop from empty chunk");
403 } else {
404 self.right -= 1;
405 unsafe { Chunk::force_read(self.right, self) }
406 }
407 }
408
409 pub fn drop_left(&mut self, index: usize) {
415 if index > 0 {
416 unsafe { ptr::drop_in_place(&mut self[..index]) }
417 self.left += index;
418 }
419 }
420
421 pub fn drop_right(&mut self, index: usize) {
427 if index != self.len() {
428 unsafe { ptr::drop_in_place(&mut self[index..]) }
429 self.right = self.left + index;
430 }
431 }
432
433 pub fn split_off(&mut self, index: usize) -> Self {
441 if index > self.len() {
442 panic!("Chunk::split_off: index out of bounds");
443 }
444 if index == self.len() {
445 return Self::new();
446 }
447 let mut right_chunk = Self::new();
448 let start = self.left + index;
449 let len = self.right - start;
450 unsafe { Chunk::force_copy_to(start, 0, len, self, &mut right_chunk) };
451 right_chunk.right = len;
452 self.right = start;
453 right_chunk
454 }
455
456 pub fn append(&mut self, other: &mut Self) {
462 let self_len = self.len();
463 let other_len = other.len();
464 if self_len + other_len > N {
465 panic!("Chunk::append: chunk size overflow");
466 }
467 if self.right + other_len > N {
468 unsafe { Chunk::force_copy(self.left, 0, self_len, self) };
469 self.right -= self.left;
470 self.left = 0;
471 }
472 unsafe { Chunk::force_copy_to(other.left, self.right, other_len, other, self) };
473 self.right += other_len;
474 other.left = 0;
475 other.right = 0;
476 }
477
478 pub fn drain_from_front(&mut self, other: &mut Self, count: usize) {
486 let self_len = self.len();
487 let other_len = other.len();
488 assert!(self_len + count <= N);
489 assert!(other_len >= count);
490 if self.right + count > N {
491 unsafe { Chunk::force_copy(self.left, 0, self_len, self) };
492 self.right -= self.left;
493 self.left = 0;
494 }
495 unsafe { Chunk::force_copy_to(other.left, self.right, count, other, self) };
496 self.right += count;
497 other.left += count;
498 }
499
500 pub fn drain_from_back(&mut self, other: &mut Self, count: usize) {
508 let self_len = self.len();
509 let other_len = other.len();
510 assert!(self_len + count <= N);
511 assert!(other_len >= count);
512 if self.left < count {
513 unsafe { Chunk::force_copy(self.left, N - self_len, self_len, self) };
514 self.left = N - self_len;
515 self.right = N;
516 }
517 unsafe { Chunk::force_copy_to(other.right - count, self.left - count, count, other, self) };
518 self.left -= count;
519 other.right -= count;
520 }
521
522 pub fn set(&mut self, index: usize, value: A) -> A {
528 replace(&mut self[index], value)
529 }
530
531 pub fn insert(&mut self, index: usize, value: A) {
538 if self.is_full() {
539 panic!("Chunk::insert: chunk is full");
540 }
541 if index > self.len() {
542 panic!("Chunk::insert: index out of bounds");
543 }
544 let real_index = index + self.left;
545 let left_size = index;
546 let right_size = self.right - real_index;
547 if self.right == N || (self.left > 0 && left_size < right_size) {
548 unsafe {
549 Chunk::force_copy(self.left, self.left - 1, left_size, self);
550 Chunk::force_write(real_index - 1, value, self);
551 }
552 self.left -= 1;
553 } else {
554 unsafe {
555 Chunk::force_copy(real_index, real_index + 1, right_size, self);
556 Chunk::force_write(real_index, value, self);
557 }
558 self.right += 1;
559 }
560 }
561
562 pub fn insert_ordered(&mut self, value: A)
581 where
582 A: Ord,
583 {
584 if self.is_full() {
585 panic!("Chunk::insert: chunk is full");
586 }
587 match self.binary_search(&value) {
588 Ok(index) => self.insert(index, value),
589 Err(index) => self.insert(index, value),
590 }
591 }
592
593 pub fn insert_from<Iterable, I>(&mut self, index: usize, iter: Iterable)
603 where
604 Iterable: IntoIterator<Item = A, IntoIter = I>,
605 I: ExactSizeIterator<Item = A>,
606 {
607 let iter = iter.into_iter();
608 let insert_size = iter.len();
609 if self.len() + insert_size > Self::CAPACITY {
610 panic!(
611 "Chunk::insert_from: chunk cannot fit {} elements",
612 insert_size
613 );
614 }
615 if index > self.len() {
616 panic!("Chunk::insert_from: index out of bounds");
617 }
618 let real_index = index + self.left;
619 let left_size = index;
620 let right_size = self.right - real_index;
621 if self.right == N || (self.left >= insert_size && left_size < right_size) {
622 unsafe {
623 Chunk::force_copy(self.left, self.left - insert_size, left_size, self);
624 let write_index = real_index - insert_size;
625 Chunk::write_from_iter(write_index, iter, self);
626 }
627 self.left -= insert_size;
628 } else if self.left == 0 || (self.right + insert_size <= Self::CAPACITY) {
629 unsafe {
630 Chunk::force_copy(real_index, real_index + insert_size, right_size, self);
631 let write_index = real_index;
632 Chunk::write_from_iter(write_index, iter, self);
633 }
634 self.right += insert_size;
635 } else {
636 unsafe {
637 Chunk::force_copy(self.left, 0, left_size, self);
638 Chunk::force_copy(real_index, left_size + insert_size, right_size, self);
639 let write_index = left_size;
640 Chunk::write_from_iter(write_index, iter, self);
641 }
642 self.right -= self.left;
643 self.right += insert_size;
644 self.left = 0;
645 }
646 }
647
648 pub fn remove(&mut self, index: usize) -> A {
657 if index >= self.len() {
658 panic!("Chunk::remove: index out of bounds");
659 }
660 let real_index = index + self.left;
661 let value = unsafe { Chunk::force_read(real_index, self) };
662 let left_size = index;
663 let right_size = self.right - real_index - 1;
664 if left_size < right_size {
665 unsafe { Chunk::force_copy(self.left, self.left + 1, left_size, self) };
666 self.left += 1;
667 } else {
668 unsafe { Chunk::force_copy(real_index + 1, real_index, right_size, self) };
669 self.right -= 1;
670 }
671 value
672 }
673
674 pub fn drain(&mut self) -> Drain<'_, A, N> {
676 Drain { chunk: self }
677 }
678
679 pub fn clear(&mut self) {
683 unsafe { ptr::drop_in_place(self.as_mut_slice()) }
684 self.left = 0;
685 self.right = 0;
686 }
687
688 pub fn as_slice(&self) -> &[A] {
690 unsafe {
691 from_raw_parts(
692 (&self.data as *const MaybeUninit<[A; N]> as *const A).add(self.left),
693 self.len(),
694 )
695 }
696 }
697
698 pub fn as_mut_slice(&mut self) -> &mut [A] {
700 unsafe {
701 from_raw_parts_mut(
702 (&mut self.data as *mut MaybeUninit<[A; N]> as *mut A).add(self.left),
703 self.len(),
704 )
705 }
706 }
707
708 pub unsafe fn as_mut_slice_ptr(this: *mut Self) -> *mut [A] {
714 unsafe {
715 let len = (*this).right - (*this).left;
717 ptr::slice_from_raw_parts_mut(ptr::addr_of_mut!((*this).data).cast(), len)
718 }
719 }
720}
721
722impl<A, const N: usize> Default for Chunk<A, N> {
723 fn default() -> Self {
724 Self::new()
725 }
726}
727
728impl<A, I, const N: usize> Index<I> for Chunk<A, N>
729where
730 I: SliceIndex<[A]>,
731{
732 type Output = I::Output;
733 fn index(&self, index: I) -> &Self::Output {
734 self.as_slice().index(index)
735 }
736}
737
738impl<A, I, const N: usize> IndexMut<I> for Chunk<A, N>
739where
740 I: SliceIndex<[A]>,
741{
742 fn index_mut(&mut self, index: I) -> &mut Self::Output {
743 self.as_mut_slice().index_mut(index)
744 }
745}
746
747impl<A, const N: usize> Debug for Chunk<A, N>
748where
749 A: Debug,
750{
751 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
752 f.write_str("Chunk")?;
753 f.debug_list().entries(self.iter()).finish()
754 }
755}
756
757impl<A, const N: usize> Hash for Chunk<A, N>
758where
759 A: Hash,
760{
761 fn hash<H>(&self, hasher: &mut H)
762 where
763 H: Hasher,
764 {
765 for item in self {
766 item.hash(hasher)
767 }
768 }
769}
770
771impl<A, Slice, const N: usize> PartialEq<Slice> for Chunk<A, N>
772where
773 Slice: Borrow<[A]>,
774 A: PartialEq,
775{
776 fn eq(&self, other: &Slice) -> bool {
777 self.as_slice() == other.borrow()
778 }
779}
780
781impl<A, const N: usize> Eq for Chunk<A, N> where A: Eq {}
782
783impl<A, const N: usize> PartialOrd for Chunk<A, N>
784where
785 A: PartialOrd,
786{
787 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
788 self.iter().partial_cmp(other.iter())
789 }
790}
791
792impl<A, const N: usize> Ord for Chunk<A, N>
793where
794 A: Ord,
795{
796 fn cmp(&self, other: &Self) -> Ordering {
797 self.iter().cmp(other.iter())
798 }
799}
800
801#[cfg(feature = "std")]
802impl<const N: usize> io::Write for Chunk<u8, N> {
803 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
804 let old_len = self.len();
805 self.extend(buf.iter().cloned().take(N - old_len));
806 Ok(self.len() - old_len)
807 }
808
809 fn flush(&mut self) -> io::Result<()> {
810 Ok(())
811 }
812}
813
814#[cfg(feature = "std")]
815impl<const N: usize> std::io::Read for Chunk<u8, N> {
816 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
817 let read_size = buf.len().min(self.len());
818 if read_size == 0 {
819 Ok(0)
820 } else {
821 for p in buf.iter_mut().take(read_size) {
822 *p = self.pop_front();
823 }
824 Ok(read_size)
825 }
826 }
827}
828
829impl<A, T, const N: usize> From<InlineArray<A, T>> for Chunk<A, N> {
830 #[inline]
831 fn from(mut array: InlineArray<A, T>) -> Self {
832 Self::from(&mut array)
833 }
834}
835
836impl<A, T, const N: usize> From<&mut InlineArray<A, T>> for Chunk<A, N> {
837 fn from(array: &mut InlineArray<A, T>) -> Self {
838 assert!(
840 InlineArray::<A, T>::CAPACITY <= Self::CAPACITY || array.len() <= Self::CAPACITY,
841 "CAPACITY too small"
842 );
843 let mut out = Self::new();
844 out.left = 0;
845 out.right = array.len();
846 unsafe {
847 ptr::copy_nonoverlapping(array.data(), out.mut_ptr(0), out.right);
848 *array.len_mut() = 0;
849 }
850 out
851 }
852}
853
854impl<A, const N: usize> Borrow<[A]> for Chunk<A, N> {
855 fn borrow(&self) -> &[A] {
856 self.as_slice()
857 }
858}
859
860impl<A, const N: usize> BorrowMut<[A]> for Chunk<A, N> {
861 fn borrow_mut(&mut self) -> &mut [A] {
862 self.as_mut_slice()
863 }
864}
865
866impl<A, const N: usize> AsRef<[A]> for Chunk<A, N> {
867 fn as_ref(&self) -> &[A] {
868 self.as_slice()
869 }
870}
871
872impl<A, const N: usize> AsMut<[A]> for Chunk<A, N> {
873 fn as_mut(&mut self) -> &mut [A] {
874 self.as_mut_slice()
875 }
876}
877
878impl<A, const N: usize> Deref for Chunk<A, N> {
879 type Target = [A];
880
881 fn deref(&self) -> &Self::Target {
882 self.as_slice()
883 }
884}
885
886impl<A, const N: usize> DerefMut for Chunk<A, N> {
887 fn deref_mut(&mut self) -> &mut Self::Target {
888 self.as_mut_slice()
889 }
890}
891
892impl<A, const N: usize> FromIterator<A> for Chunk<A, N> {
893 fn from_iter<I>(it: I) -> Self
894 where
895 I: IntoIterator<Item = A>,
896 {
897 let mut chunk = Self::new();
898 for item in it {
899 chunk.push_back(item);
900 }
901 chunk
902 }
903}
904
905impl<'a, A, const N: usize> IntoIterator for &'a Chunk<A, N> {
906 type Item = &'a A;
907 type IntoIter = SliceIter<'a, A>;
908 fn into_iter(self) -> Self::IntoIter {
909 self.iter()
910 }
911}
912
913impl<'a, A, const N: usize> IntoIterator for &'a mut Chunk<A, N> {
914 type Item = &'a mut A;
915 type IntoIter = SliceIterMut<'a, A>;
916 fn into_iter(self) -> Self::IntoIter {
917 self.iter_mut()
918 }
919}
920
921impl<A, const N: usize> Extend<A> for Chunk<A, N> {
922 fn extend<I>(&mut self, it: I)
928 where
929 I: IntoIterator<Item = A>,
930 {
931 for item in it {
932 self.push_back(item);
933 }
934 }
935}
936
937impl<'a, A, const N: usize> Extend<&'a A> for Chunk<A, N>
938where
939 A: 'a + Copy,
940{
941 fn extend<I>(&mut self, it: I)
947 where
948 I: IntoIterator<Item = &'a A>,
949 {
950 for item in it {
951 self.push_back(*item);
952 }
953 }
954}
955
956impl<A, const N: usize> IntoIterator for Chunk<A, N> {
957 type Item = A;
958 type IntoIter = Iter<A, N>;
959
960 fn into_iter(self) -> Self::IntoIter {
961 Iter { chunk: self }
962 }
963}
964
965#[cfg(test)]
966#[rustfmt::skip]
967mod test {
968 use super::*;
969
970 #[test]
971 #[should_panic(expected = "Chunk::push_back: can't push to full chunk")]
972 fn issue_11_testcase1d() {
973 let mut chunk = Chunk::<usize, 2>::pair(123, 456);
974 chunk.push_back(789);
975 }
976
977 #[test]
978 #[should_panic(expected = "CAPACITY too small")]
979 fn issue_11_testcase2a() {
980 let mut from = InlineArray::<u8, [u8; 256]>::new();
981 from.push(1);
982
983 let _ = Chunk::<u8, 0>::from(from);
984 }
985
986 #[test]
987 fn issue_11_testcase2b() {
988 let mut from = InlineArray::<u8, [u8; 256]>::new();
989 from.push(1);
990
991 let _ = Chunk::<u8, 1>::from(from);
992 }
993
994 struct DropDetector(u32);
995
996 impl DropDetector {
997 fn new(num: u32) -> Self {
998 DropDetector(num)
999 }
1000 }
1001
1002 impl Drop for DropDetector {
1003 fn drop(&mut self) {
1004 assert!(self.0 == 42 || self.0 == 43);
1005 }
1006 }
1007
1008 impl Clone for DropDetector {
1009 fn clone(&self) -> Self {
1010 if self.0 == 42 {
1011 panic!("panic on clone")
1012 }
1013 DropDetector::new(self.0)
1014 }
1015 }
1016
1017 #[test]
1019 fn issue_11_testcase3a() {
1020 let mut chunk = Chunk::<DropDetector, 3>::new();
1021 chunk.push_back(DropDetector::new(42));
1022 chunk.push_back(DropDetector::new(42));
1023 chunk.push_back(DropDetector::new(43));
1024 let _ = chunk.pop_front();
1025
1026 let _ = std::panic::catch_unwind(|| {
1027 let _ = chunk.clone();
1028 });
1029 }
1030
1031 struct PanickingIterator {
1032 current: u32,
1033 panic_at: u32,
1034 len: usize,
1035 }
1036
1037 impl Iterator for PanickingIterator {
1038 type Item = DropDetector;
1039
1040 fn next(&mut self) -> Option<Self::Item> {
1041 let num = self.current;
1042
1043 if num == self.panic_at {
1044 panic!("panicking index")
1045 }
1046
1047 self.current += 1;
1048 Some(DropDetector::new(num))
1049 }
1050
1051 fn size_hint(&self) -> (usize, Option<usize>) {
1052 (self.len, Some(self.len))
1053 }
1054 }
1055
1056 impl ExactSizeIterator for PanickingIterator {}
1057
1058 #[test]
1059 fn issue_11_testcase3b() {
1060 let _ = std::panic::catch_unwind(|| {
1061 let mut chunk = Chunk::<DropDetector, 5>::new();
1062 chunk.push_back(DropDetector::new(1));
1063 chunk.push_back(DropDetector::new(2));
1064 chunk.push_back(DropDetector::new(3));
1065
1066 chunk.insert_from(
1067 1,
1068 PanickingIterator {
1069 current: 1,
1070 panic_at: 1,
1071 len: 1,
1072 },
1073 );
1074 });
1075 }
1076
1077 struct FakeSizeIterator { reported: usize, actual: usize }
1078 impl Iterator for FakeSizeIterator {
1079 type Item = u8;
1080 fn next(&mut self) -> Option<Self::Item> {
1081 if self.actual == 0 {
1082 None
1083 } else {
1084 self.actual -= 1;
1085 Some(1)
1086 }
1087 }
1088
1089 fn size_hint(&self) -> (usize, Option<usize>) {
1090 (self.reported, Some(self.reported))
1091 }
1092 }
1093
1094 impl ExactSizeIterator for FakeSizeIterator {
1095 fn len(&self) -> usize {
1096 self.reported
1097 }
1098 }
1099
1100 #[test]
1101 fn iterator_too_long() {
1102 let mut chunk = Chunk::<u8, 5>::new();
1103 chunk.push_back(0);
1104 chunk.push_back(1);
1105 chunk.push_back(2);
1106 chunk.insert_from(1, FakeSizeIterator { reported: 1, actual: 10 });
1107
1108 let mut chunk = Chunk::<u8, 5>::new();
1109 chunk.push_back(1);
1110 chunk.insert_from(0, FakeSizeIterator { reported: 1, actual: 10 });
1111
1112 let mut chunk = Chunk::<u8, 5>::new();
1113 chunk.insert_from(0, FakeSizeIterator { reported: 1, actual: 10 });
1114 }
1115
1116 #[test]
1117 #[should_panic(expected = "ExactSizeIterator yielded fewer values than advertised")]
1118 fn iterator_too_short1() {
1119 let mut chunk = Chunk::<u8, 5>::new();
1120 chunk.push_back(0);
1121 chunk.push_back(1);
1122 chunk.push_back(2);
1123 chunk.insert_from(1, FakeSizeIterator { reported: 2, actual: 0 });
1124 }
1125
1126 #[test]
1127 #[should_panic(expected = "ExactSizeIterator yielded fewer values than advertised")]
1128 fn iterator_too_short2() {
1129 let mut chunk = Chunk::<u8, 5>::new();
1130 chunk.push_back(1);
1131 chunk.insert_from(1, FakeSizeIterator { reported: 4, actual: 2 });
1132 }
1133
1134 #[test]
1135 fn is_full() {
1136 let mut chunk = Chunk::<_, 64>::new();
1137 for i in 0..64 {
1138 assert!(!chunk.is_full());
1139 chunk.push_back(i);
1140 }
1141 assert!(chunk.is_full());
1142 }
1143
1144 #[test]
1145 fn push_back_front() {
1146 let mut chunk = Chunk::<_, 64>::new();
1147 for i in 12..20 {
1148 chunk.push_back(i);
1149 }
1150 assert_eq!(8, chunk.len());
1151 for i in (0..12).rev() {
1152 chunk.push_front(i);
1153 }
1154 assert_eq!(20, chunk.len());
1155 for i in 20..32 {
1156 chunk.push_back(i);
1157 }
1158 assert_eq!(32, chunk.len());
1159 let right: Vec<i32> = chunk.into_iter().collect();
1160 let left: Vec<i32> = (0..32).collect();
1161 assert_eq!(left, right);
1162 }
1163
1164 #[test]
1165 fn push_and_pop() {
1166 let mut chunk = Chunk::<_, 64>::new();
1167 for i in 0..64 {
1168 chunk.push_back(i);
1169 }
1170 for i in 0..64 {
1171 assert_eq!(i, chunk.pop_front());
1172 }
1173 for i in 0..64 {
1174 chunk.push_front(i);
1175 }
1176 for i in 0..64 {
1177 assert_eq!(i, chunk.pop_back());
1178 }
1179 }
1180
1181 #[test]
1182 fn drop_left() {
1183 let mut chunk = Chunk::<_, 64>::new();
1184 for i in 0..6 {
1185 chunk.push_back(i);
1186 }
1187 chunk.drop_left(3);
1188 let vec: Vec<i32> = chunk.into_iter().collect();
1189 assert_eq!(vec![3, 4, 5], vec);
1190 }
1191
1192 #[test]
1193 fn drop_right() {
1194 let mut chunk = Chunk::<_, 64>::new();
1195 for i in 0..6 {
1196 chunk.push_back(i);
1197 }
1198 chunk.drop_right(3);
1199 let vec: Vec<i32> = chunk.into_iter().collect();
1200 assert_eq!(vec![0, 1, 2], vec);
1201 }
1202
1203 #[test]
1204 fn split_off() {
1205 let mut left = Chunk::<_, 64>::new();
1206 for i in 0..6 {
1207 left.push_back(i);
1208 }
1209 let right = left.split_off(3);
1210 let left_vec: Vec<i32> = left.into_iter().collect();
1211 let right_vec: Vec<i32> = right.into_iter().collect();
1212 assert_eq!(vec![0, 1, 2], left_vec);
1213 assert_eq!(vec![3, 4, 5], right_vec);
1214 }
1215
1216 #[test]
1217 fn append() {
1218 let mut left = Chunk::<_, 64>::new();
1219 for i in 0..32 {
1220 left.push_back(i);
1221 }
1222 let mut right = Chunk::<_, 64>::new();
1223 for i in (32..64).rev() {
1224 right.push_front(i);
1225 }
1226 left.append(&mut right);
1227 let out_vec: Vec<i32> = left.into_iter().collect();
1228 let should_vec: Vec<i32> = (0..64).collect();
1229 assert_eq!(should_vec, out_vec);
1230 }
1231
1232 #[test]
1233 fn ref_iter() {
1234 let mut chunk = Chunk::<_, 64>::new();
1235 for i in 0..64 {
1236 chunk.push_back(i);
1237 }
1238 let out_vec: Vec<&i32> = chunk.iter().collect();
1239 let should_vec_p: Vec<i32> = (0..64).collect();
1240 let should_vec: Vec<&i32> = should_vec_p.iter().collect();
1241 assert_eq!(should_vec, out_vec);
1242 }
1243
1244 #[test]
1245 fn mut_ref_iter() {
1246 let mut chunk = Chunk::<_, 64>::new();
1247 for i in 0..64 {
1248 chunk.push_back(i);
1249 }
1250 let out_vec: Vec<&mut i32> = chunk.iter_mut().collect();
1251 let mut should_vec_p: Vec<i32> = (0..64).collect();
1252 let should_vec: Vec<&mut i32> = should_vec_p.iter_mut().collect();
1253 assert_eq!(should_vec, out_vec);
1254 }
1255
1256 #[test]
1257 fn consuming_iter() {
1258 let mut chunk = Chunk::<_, 64>::new();
1259 for i in 0..64 {
1260 chunk.push_back(i);
1261 }
1262 let out_vec: Vec<i32> = chunk.into_iter().collect();
1263 let should_vec: Vec<i32> = (0..64).collect();
1264 assert_eq!(should_vec, out_vec);
1265 }
1266
1267 #[test]
1268 fn insert_middle() {
1269 let mut chunk = Chunk::<_, 64>::new();
1270 for i in 0..32 {
1271 chunk.push_back(i);
1272 }
1273 for i in 33..64 {
1274 chunk.push_back(i);
1275 }
1276 chunk.insert(32, 32);
1277 let out_vec: Vec<i32> = chunk.into_iter().collect();
1278 let should_vec: Vec<i32> = (0..64).collect();
1279 assert_eq!(should_vec, out_vec);
1280 }
1281
1282 #[test]
1283 fn insert_back() {
1284 let mut chunk = Chunk::<_, 64>::new();
1285 for i in 0..63 {
1286 chunk.push_back(i);
1287 }
1288 chunk.insert(63, 63);
1289 let out_vec: Vec<i32> = chunk.into_iter().collect();
1290 let should_vec: Vec<i32> = (0..64).collect();
1291 assert_eq!(should_vec, out_vec);
1292 }
1293
1294 #[test]
1295 fn insert_front() {
1296 let mut chunk = Chunk::<_, 64>::new();
1297 for i in 1..64 {
1298 chunk.push_front(64 - i);
1299 }
1300 chunk.insert(0, 0);
1301 let out_vec: Vec<i32> = chunk.into_iter().collect();
1302 let should_vec: Vec<i32> = (0..64).collect();
1303 assert_eq!(should_vec, out_vec);
1304 }
1305
1306 #[test]
1307 fn remove_value() {
1308 let mut chunk = Chunk::<_, 64>::new();
1309 for i in 0..64 {
1310 chunk.push_back(i);
1311 }
1312 chunk.remove(32);
1313 let out_vec: Vec<i32> = chunk.into_iter().collect();
1314 let should_vec: Vec<i32> = (0..32).chain(33..64).collect();
1315 assert_eq!(should_vec, out_vec);
1316 }
1317
1318 use crate::tests::DropTest;
1319 use std::sync::atomic::{AtomicUsize, Ordering};
1320
1321 #[test]
1322 fn dropping() {
1323 let counter = AtomicUsize::new(0);
1324 {
1325 let mut chunk: Chunk<DropTest<'_>, 64> = Chunk::new();
1326 for _i in 0..20 {
1327 chunk.push_back(DropTest::new(&counter))
1328 }
1329 for _i in 0..20 {
1330 chunk.push_front(DropTest::new(&counter))
1331 }
1332 assert_eq!(40, counter.load(Ordering::Relaxed));
1333 for _i in 0..10 {
1334 chunk.pop_back();
1335 }
1336 assert_eq!(30, counter.load(Ordering::Relaxed));
1337 }
1338 assert_eq!(0, counter.load(Ordering::Relaxed));
1339 }
1340
1341 #[test]
1342 #[should_panic(expected = "assertion failed: Self::CAPACITY >= 1")]
1343 fn unit_on_empty() {
1344 Chunk::<usize, 0>::unit(1);
1345 }
1346
1347 #[test]
1348 #[should_panic(expected = "assertion failed: Self::CAPACITY >= 2")]
1349 fn pair_on_empty() {
1350 Chunk::<usize, 0>::pair(1, 2);
1351 }
1352}