1#[cfg(feature = "stable_deref_trait")]
4use stable_deref_trait::StableDeref;
5
6use std::cmp::Ordering;
7use std::convert::{AsMut, AsRef};
8use std::fmt::{Debug, Display, Formatter, Pointer, Result as FormatResult};
9use std::hash::{Hash, Hasher};
10use std::iter::{DoubleEndedIterator, FromIterator, IntoIterator};
11use std::marker::Unpin;
12use std::mem::{forget, MaybeUninit};
13use std::ops::{Deref, DerefMut};
14use std::pin::Pin;
15use std::ptr::{copy_nonoverlapping, drop_in_place, read, write};
16use std::slice::{Iter, IterMut};
17use std::str::{from_utf8, Utf8Error};
18use std::{
19 borrow::{Borrow, BorrowMut},
20 ptr::NonNull,
21};
22
23use crate::internal::{gen_free, gen_malloc, gen_realloc, Unique};
24
25#[cfg(all(test, not(windows)))]
26use crate::internal::DropCounter;
27#[cfg(test)]
28use crate::internal::PanicOnClone;
29#[cfg(test)]
30use std::iter::{once, repeat};
31#[cfg(all(test, not(windows)))]
32use std::mem::size_of;
33
34#[cfg(feature = "nightly")]
35use std::marker::Unsize;
36#[cfg(feature = "nightly")]
37use std::ops::CoerceUnsized;
38
39use crate::free::Free;
40
41pub struct MBox<T: ?Sized + Free>(Unique<T>);
45
46impl<T: ?Sized + Free> MBox<T> {
47 pub unsafe fn from_raw(ptr: *mut T) -> Self {
60 Self::from_non_null_raw(NonNull::new_unchecked(ptr))
61 }
62
63 pub unsafe fn from_non_null_raw(ptr: NonNull<T>) -> Self {
76 Self(Unique::new(ptr))
77 }
78
79 pub fn as_ptr(boxed: &Self) -> *const T {
81 boxed.0.as_non_null_ptr().as_ptr()
82 }
83
84 pub fn as_mut_ptr(boxed: &mut Self) -> *mut T {
86 boxed.0.as_non_null_ptr().as_ptr()
87 }
88
89 pub fn into_raw(boxed: Self) -> *mut T {
93 Self::into_non_null_raw(boxed).as_ptr()
94 }
95
96 pub fn into_non_null_raw(boxed: Self) -> NonNull<T> {
100 let ptr = boxed.0.as_non_null_ptr();
101 forget(boxed);
102 ptr
103 }
104}
105
106impl<T: ?Sized + Free> Drop for MBox<T> {
107 fn drop(&mut self) {
108 unsafe { T::free(self.0.as_non_null_ptr()) };
110 }
111}
112
113impl<T: ?Sized + Free> Deref for MBox<T> {
114 type Target = T;
115 fn deref(&self) -> &T {
116 unsafe { &*Self::as_ptr(self) }
117 }
118}
119
120#[cfg(feature = "stable_deref_trait")]
121unsafe impl<T: ?Sized + Free> StableDeref for MBox<T> {}
122
123impl<T: ?Sized + Free> Unpin for MBox<T> {}
124
125impl<T: ?Sized + Free> DerefMut for MBox<T> {
126 fn deref_mut(&mut self) -> &mut T {
127 unsafe { &mut *Self::as_mut_ptr(self) }
128 }
129}
130
131impl<T: ?Sized + Free> AsRef<T> for MBox<T> {
132 fn as_ref(&self) -> &T {
133 self
134 }
135}
136
137impl<T: ?Sized + Free> AsMut<T> for MBox<T> {
138 fn as_mut(&mut self) -> &mut T {
139 self
140 }
141}
142
143impl<T: ?Sized + Free> Borrow<T> for MBox<T> {
144 fn borrow(&self) -> &T {
145 self
146 }
147}
148
149impl<T: ?Sized + Free> BorrowMut<T> for MBox<T> {
150 fn borrow_mut(&mut self) -> &mut T {
151 self
152 }
153}
154
155#[cfg(feature = "nightly")]
156impl<T: ?Sized + Free + Unsize<U>, U: ?Sized + Free> CoerceUnsized<MBox<U>> for MBox<T> {}
157
158impl<T: ?Sized + Free> Pointer for MBox<T> {
159 fn fmt(&self, formatter: &mut Formatter) -> FormatResult {
160 Pointer::fmt(&Self::as_ptr(self), formatter)
161 }
162}
163
164impl<T: ?Sized + Free + Debug> Debug for MBox<T> {
165 fn fmt(&self, formatter: &mut Formatter) -> FormatResult {
166 self.deref().fmt(formatter)
167 }
168}
169
170impl<T: ?Sized + Free + Display> Display for MBox<T> {
171 fn fmt(&self, formatter: &mut Formatter) -> FormatResult {
172 self.deref().fmt(formatter)
173 }
174}
175
176impl<T: ?Sized + Free + Hash> Hash for MBox<T> {
177 fn hash<H: Hasher>(&self, state: &mut H) {
178 self.deref().hash(state)
179 }
180}
181
182impl<U: ?Sized + Free, T: ?Sized + Free + PartialEq<U>> PartialEq<MBox<U>> for MBox<T> {
183 fn eq(&self, other: &MBox<U>) -> bool {
184 self.deref().eq(other.deref())
185 }
186}
187
188impl<T: ?Sized + Free + Eq> Eq for MBox<T> {}
189
190impl<U: ?Sized + Free, T: ?Sized + Free + PartialOrd<U>> PartialOrd<MBox<U>> for MBox<T> {
191 fn partial_cmp(&self, other: &MBox<U>) -> Option<Ordering> {
192 self.deref().partial_cmp(other.deref())
193 }
194}
195
196impl<T: ?Sized + Free + Ord> Ord for MBox<T> {
197 fn cmp(&self, other: &Self) -> Ordering {
198 self.deref().cmp(other.deref())
199 }
200}
201
202impl<T> MBox<T> {
207 pub fn new(value: T) -> Self {
209 let storage = gen_malloc(1);
210 unsafe {
213 write(storage.as_ptr(), value);
214 Self::from_non_null_raw(storage)
215 }
216 }
217
218 pub fn new_uninit() -> MBox<MaybeUninit<T>> {
220 let storage = gen_malloc(1);
221 unsafe { MBox::from_non_null_raw(storage) }
223 }
224
225 pub fn pin(value: T) -> Pin<Self> {
228 Self::into_pin(Self::new(value))
229 }
230
231 pub fn into_boxed_slice(boxed: Self) -> MBox<[T]> {
235 unsafe { MBox::from_raw_parts(Self::into_raw(boxed), 1) }
238 }
239
240 pub fn into_inner(boxed: Self) -> T {
242 let mut dst = MaybeUninit::uninit();
243 let src = Self::into_non_null_raw(boxed);
244 unsafe {
249 copy_nonoverlapping(src.as_ptr(), dst.as_mut_ptr(), 1);
250 gen_free(src);
251 dst.assume_init()
252 }
253 }
254
255 pub fn into_pin(boxed: Self) -> Pin<Self> {
259 unsafe { Pin::new_unchecked(boxed) }
261 }
262
263 pub fn leak<'a>(boxed: Self) -> &'a mut T
265 where
266 T: 'a,
267 {
268 unsafe { &mut *Self::into_non_null_raw(boxed).as_ptr() }
272 }
273}
274
275impl<T> MBox<MaybeUninit<T>> {
276 pub unsafe fn assume_init(self) -> MBox<T> {
282 MBox::from_non_null_raw(Self::into_non_null_raw(self).cast())
283 }
284}
285
286impl<T> From<T> for MBox<T> {
287 fn from(value: T) -> MBox<T> {
288 MBox::new(value)
289 }
290}
291
292impl<T: Clone> Clone for MBox<T> {
293 fn clone(&self) -> MBox<T> {
294 Self::new(self.deref().clone())
295 }
296
297 fn clone_from(&mut self, source: &Self) {
298 self.deref_mut().clone_from(source);
299 }
300}
301
302impl<T: Default> Default for MBox<T> {
303 fn default() -> MBox<T> {
304 MBox::new(T::default())
305 }
306}
307
308#[cfg(not(windows))]
309#[test]
310fn test_single_object() {
311 let counter = DropCounter::default();
312 {
313 let mbox = MBox::new(counter.clone());
314 counter.assert_eq(0);
315 drop(mbox);
316 }
317 counter.assert_eq(1);
318}
319
320#[test]
321fn test_into_raw() {
322 let mbox = MBox::new(66u8);
323 let raw = MBox::into_raw(mbox);
324 unsafe {
325 assert_eq!(*raw, 66u8);
326 gen_free(NonNull::new(raw).unwrap());
327 }
328}
329
330#[cfg(not(windows))]
331#[test]
332fn test_clone() {
333 let counter = DropCounter::default();
334 {
335 let first_mbox = MBox::new(counter.clone());
336 {
337 let second_mbox = first_mbox.clone();
338 counter.assert_eq(0);
339 drop(second_mbox);
340 }
341 counter.assert_eq(1);
342 }
343 counter.assert_eq(2);
344}
345
346#[cfg(not(windows))]
347#[test]
348fn test_clone_from() {
349 let counter = DropCounter::default();
350 {
351 let first_mbox = MBox::new(counter.clone());
352 {
353 let mut second_mbox = MBox::new(counter.clone());
354 counter.assert_eq(0);
355 second_mbox.clone_from(&first_mbox);
356 counter.assert_eq(1);
357 }
358 counter.assert_eq(2);
359 }
360 counter.assert_eq(3);
361}
362
363#[cfg(not(windows))]
364#[test]
365fn test_no_drop_flag() {
366 fn do_test_for_drop_flag(branch: bool, expected: usize) {
367 let counter = DropCounter::default();
368 let inner_counter = counter.deref().clone();
369 {
370 let mbox;
371 if branch {
372 mbox = MBox::new(counter.clone());
373 let _ = &mbox;
374 }
375 inner_counter.assert_eq(0);
376 }
377 inner_counter.assert_eq(expected);
378 }
379
380 do_test_for_drop_flag(true, 1);
381 do_test_for_drop_flag(false, 0);
382
383 assert_eq!(
384 size_of::<MBox<DropCounter>>(),
385 size_of::<*mut DropCounter>()
386 );
387}
388
389#[cfg(feature = "std")]
390#[test]
391fn test_format() {
392 let a = MBox::new(3u8);
393 assert_eq!(format!("{:p}", a), format!("{:p}", MBox::as_ptr(&a)));
394 assert_eq!(format!("{}", a), "3");
395 assert_eq!(format!("{:?}", a), "3");
396}
397
398#[test]
399fn test_standard_traits() {
400 let mut a = MBox::new(0u8);
401 assert_eq!(*a, 0);
402 *a = 3;
403 assert_eq!(*a, 3);
404 assert_eq!(*a.as_ref(), 3);
405 assert_eq!(*a.as_mut(), 3);
406 assert_eq!(*(a.borrow() as &u8), 3);
407 assert_eq!(*(a.borrow_mut() as &mut u8), 3);
408 assert!(a == MBox::new(3u8));
409 assert!(a != MBox::new(0u8));
410 assert!(a < MBox::new(4u8));
411 assert!(a > MBox::new(2u8));
412 assert!(a <= MBox::new(4u8));
413 assert!(a >= MBox::new(2u8));
414 assert_eq!(a.cmp(&MBox::new(7u8)), Ordering::Less);
415 assert_eq!(MBox::<u8>::default(), MBox::new(0u8));
416}
417
418#[test]
419fn test_zero_sized_type() {
420 let a = MBox::new(());
421 assert!(!MBox::as_ptr(&a).is_null());
422}
423
424#[cfg(not(windows))]
425#[test]
426fn test_non_zero() {
427 let b = 0u64;
428 assert!(!Some(MBox::new(0u64)).is_none());
429 assert!(!Some(MBox::new(())).is_none());
430 assert!(!Some(MBox::new(&b)).is_none());
431
432 assert_eq!(size_of::<Option<MBox<u64>>>(), size_of::<MBox<u64>>());
433 assert_eq!(size_of::<Option<MBox<()>>>(), size_of::<MBox<()>>());
434 assert_eq!(
435 size_of::<Option<MBox<&'static u64>>>(),
436 size_of::<MBox<&'static u64>>()
437 );
438}
439
440#[cfg(not(windows))]
441#[test]
442fn test_aligned() {
443 use std::mem::align_of;
444
445 let b = MBox::new(1u16);
446 assert_eq!(MBox::as_ptr(&b) as usize % align_of::<u16>(), 0);
447
448 let b = MBox::new(1u32);
449 assert_eq!(MBox::as_ptr(&b) as usize % align_of::<u32>(), 0);
450
451 let b = MBox::new(1u64);
452 assert_eq!(MBox::as_ptr(&b) as usize % align_of::<u64>(), 0);
453
454 #[repr(C, align(4096))]
455 struct A(u8);
456
457 let b = MBox::new(A(2));
458 assert_eq!(MBox::as_ptr(&b) as usize % 4096, 0);
459}
460
461mod slice_helper {
466 use super::*;
467
468 pub struct MSliceBuilder<T> {
470 ptr: NonNull<T>,
471 cap: usize,
472 len: usize,
473 }
474
475 impl<T> MSliceBuilder<T> {
476 pub fn with_capacity(cap: usize) -> MSliceBuilder<T> {
478 MSliceBuilder {
479 ptr: gen_malloc(cap),
480 cap,
481 len: 0,
482 }
483 }
484
485 pub fn push(&mut self, obj: T) {
486 if self.len >= self.cap {
487 let new_cap = (self.cap * 2).max(1);
488 unsafe {
491 self.ptr = gen_realloc(self.ptr, self.cap, new_cap);
492 }
493 self.cap = new_cap;
494 }
495
496 unsafe {
502 write(self.ptr.as_ptr().add(self.len), obj);
503 }
504 self.len += 1;
505 }
506
507 pub fn into_mboxed_slice(self) -> MBox<[T]> {
508 let slice = unsafe { MBox::from_raw_parts(self.ptr.as_ptr(), self.len) };
511 forget(self);
512 slice
513 }
514 }
515
516 impl<T> MSliceBuilder<MaybeUninit<T>> {
517 pub fn set_len_to_cap(&mut self) {
520 self.len = self.cap;
521 }
522 }
523
524 impl<T> Drop for MSliceBuilder<T> {
525 fn drop(&mut self) {
526 unsafe {
528 gen_free(self.ptr);
529 }
530 }
531 }
532
533 #[repr(C)]
534 struct SliceParts<T> {
535 ptr: *mut T,
536 len: usize,
537 }
538
539 impl<T> Clone for SliceParts<T> {
540 fn clone(&self) -> Self {
541 Self {
542 ptr: self.ptr,
543 len: self.len,
544 }
545 }
546 }
547 impl<T> Copy for SliceParts<T> {}
548
549 #[repr(C)]
550 union SliceTransformer<T> {
551 fat_ptr: *mut [T],
552 parts: SliceParts<T>,
553 }
554
555 pub fn slice_from_raw_parts_mut<T>(ptr: *mut T, len: usize) -> *mut [T] {
557 unsafe {
559 SliceTransformer {
560 parts: SliceParts { ptr, len },
561 }
562 .fat_ptr
563 }
564 }
565
566 pub fn slice_into_raw_parts_mut<T>(fat_ptr: *mut [T]) -> (*mut T, usize) {
567 let parts = unsafe { SliceTransformer { fat_ptr }.parts };
568 (parts.ptr, parts.len)
569 }
570}
571
572use self::slice_helper::{slice_from_raw_parts_mut, slice_into_raw_parts_mut, MSliceBuilder};
573
574pub struct MSliceIntoIter<T> {
576 ptr: NonNull<T>,
577 begin: usize,
578 end: usize,
579}
580
581impl<T> Iterator for MSliceIntoIter<T> {
582 type Item = T;
583
584 fn next(&mut self) -> Option<T> {
585 if self.begin == self.end {
586 None
587 } else {
588 unsafe {
589 let ptr = self.ptr.as_ptr().add(self.begin);
590 self.begin += 1;
591 Some(read(ptr))
592 }
593 }
594 }
595
596 fn size_hint(&self) -> (usize, Option<usize>) {
597 let len = self.end - self.begin;
598 (len, Some(len))
599 }
600}
601
602impl<T> DoubleEndedIterator for MSliceIntoIter<T> {
603 fn next_back(&mut self) -> Option<T> {
604 if self.begin == self.end {
605 None
606 } else {
607 unsafe {
608 self.end -= 1;
609 let ptr = self.ptr.as_ptr().add(self.end);
610 Some(read(ptr))
611 }
612 }
613 }
614}
615
616unsafe impl<T: Send> Send for MSliceIntoIter<T> {}
617unsafe impl<T: Sync> Sync for MSliceIntoIter<T> {}
618
619impl<T> ExactSizeIterator for MSliceIntoIter<T> {}
620
621impl<T> Drop for MSliceIntoIter<T> {
622 fn drop(&mut self) {
623 unsafe {
624 let base = self.ptr.as_ptr().add(self.begin);
625 let len = self.end - self.begin;
626 let slice = slice_from_raw_parts_mut(base, len);
627 drop_in_place(slice);
628 gen_free(self.ptr);
629 }
630 }
631}
632
633impl<T> MBox<[T]> {
638 pub unsafe fn from_raw_parts(ptr: *mut T, len: usize) -> Self {
647 Self::from_raw(slice_from_raw_parts_mut(ptr, len))
648 }
649
650 pub fn new_uninit_slice(len: usize) -> MBox<[MaybeUninit<T>]> {
652 let mut builder = MSliceBuilder::with_capacity(len);
653 builder.set_len_to_cap();
654 builder.into_mboxed_slice()
655 }
656
657 pub fn into_raw_parts(mut self) -> (*mut T, usize) {
659 let (ptr, len) = slice_into_raw_parts_mut(Self::as_mut_ptr(&mut self));
660 forget(self);
661 (ptr, len)
662 }
663}
664
665impl<T> MBox<[MaybeUninit<T>]> {
666 pub unsafe fn assume_init(self) -> MBox<[T]> {
672 MBox::from_raw(Self::into_raw(self) as *mut [T])
673 }
674}
675
676impl<T> Default for MBox<[T]> {
677 fn default() -> Self {
678 unsafe { Self::from_raw_parts(gen_malloc(0).as_ptr(), 0) }
679 }
680}
681
682impl<T: Clone> Clone for MBox<[T]> {
683 fn clone(&self) -> Self {
684 Self::from_slice(self)
685 }
686}
687
688impl<T: Clone> MBox<[T]> {
689 pub fn from_slice(slice: &[T]) -> MBox<[T]> {
691 let mut builder = MSliceBuilder::with_capacity(slice.len());
692 for item in slice {
693 builder.push(item.clone());
694 }
695 builder.into_mboxed_slice()
696 }
697}
698
699impl<T> FromIterator<T> for MBox<[T]> {
700 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
701 let iter = iter.into_iter();
702 let (lower_size, upper_size) = iter.size_hint();
703 let initial_capacity = upper_size.unwrap_or(lower_size).max(1);
704 let mut builder = MSliceBuilder::with_capacity(initial_capacity);
705 for item in iter {
706 builder.push(item);
707 }
708 builder.into_mboxed_slice()
709 }
710}
711
712impl<T> IntoIterator for MBox<[T]> {
713 type Item = T;
714 type IntoIter = MSliceIntoIter<T>;
715 fn into_iter(self) -> MSliceIntoIter<T> {
716 let (ptr, len) = self.into_raw_parts();
717 MSliceIntoIter {
718 ptr: unsafe { NonNull::new_unchecked(ptr) },
719 begin: 0,
720 end: len,
721 }
722 }
723}
724
725impl<'a, T> IntoIterator for &'a MBox<[T]> {
726 type Item = &'a T;
727 type IntoIter = Iter<'a, T>;
728 fn into_iter(self) -> Iter<'a, T> {
729 self.iter()
730 }
731}
732
733impl<'a, T> IntoIterator for &'a mut MBox<[T]> {
734 type Item = &'a mut T;
735 type IntoIter = IterMut<'a, T>;
736 fn into_iter(self) -> IterMut<'a, T> {
737 self.iter_mut()
738 }
739}
740
741#[cfg(not(windows))]
742#[test]
743fn test_slice() {
744 unsafe {
745 let slice_content = gen_malloc::<u64>(5).as_ptr();
746 *slice_content.offset(0) = 16458340076686561191;
747 *slice_content.offset(1) = 15635007859502065083;
748 *slice_content.offset(2) = 4845947824042606450;
749 *slice_content.offset(3) = 8907026173756975745;
750 *slice_content.offset(4) = 7378932587879886134;
751 let mbox = MBox::from_raw_parts(slice_content, 5);
752 assert_eq!(
753 &mbox as &[u64],
754 &[
755 16458340076686561191,
756 15635007859502065083,
757 4845947824042606450,
758 8907026173756975745,
759 7378932587879886134
760 ]
761 );
762 }
763}
764
765#[cfg(not(windows))]
766#[test]
767fn test_slice_with_drops() {
768 let counter = DropCounter::default();
769 unsafe {
770 let slice_content = gen_malloc::<DropCounter>(3).as_ptr();
771 {
772 write(slice_content.offset(0), counter.clone());
773 write(slice_content.offset(1), counter.clone());
774 write(slice_content.offset(2), counter.clone());
775 }
776 counter.assert_eq(0);
777 let mbox = MBox::from_raw_parts(slice_content, 3);
778 mbox[0].assert_eq(0);
779 mbox[1].assert_eq(0);
780 mbox[2].assert_eq(0);
781 assert_eq!(mbox.len(), 3);
782 }
783 counter.assert_eq(3);
784}
785
786#[cfg(feature = "nightly")]
787#[test]
788fn test_coerce_unsized() {
789 let counter = DropCounter::default();
790 {
791 let pre_box = MBox::new([counter.clone(), counter.clone()]);
792 counter.assert_eq(0);
793 pre_box[0].assert_eq(0);
794 pre_box[1].assert_eq(0);
795 assert_eq!(pre_box.len(), 2);
796
797 let post_box: MBox<[DropCounter]> = pre_box;
798 counter.assert_eq(0);
799 post_box[0].assert_eq(0);
800 post_box[1].assert_eq(0);
801 assert_eq!(post_box.len(), 2);
802 }
803 counter.assert_eq(2);
804}
805
806#[cfg(not(windows))]
807#[test]
808#[allow(useless_ptr_null_checks)]
809fn test_empty_slice() {
810 let mbox = MBox::<[DropCounter]>::default();
811 let sl: &[DropCounter] = &mbox;
812 assert_eq!(sl.len(), 0);
813 assert!(!sl.as_ptr().is_null());
814}
815
816#[cfg(all(feature = "nightly", not(windows)))]
817#[test]
818#[allow(useless_ptr_null_checks)]
819fn test_coerce_from_empty_slice() {
820 let pre_box = MBox::<[DropCounter; 0]>::new([]);
821 assert_eq!(pre_box.len(), 0);
822 assert!(!pre_box.as_ptr().is_null());
823
824 let post_box: MBox<[DropCounter]> = pre_box;
825 let sl: &[DropCounter] = &post_box;
826 assert_eq!(sl.len(), 0);
827 assert!(!sl.as_ptr().is_null());
828}
829
830#[cfg(not(windows))]
831#[test]
832fn test_clone_slice() {
833 let counter = DropCounter::default();
834 unsafe {
835 let slice_content = gen_malloc::<DropCounter>(3).as_ptr();
836 {
837 write(slice_content.offset(0), counter.clone());
838 write(slice_content.offset(1), counter.clone());
839 write(slice_content.offset(2), counter.clone());
840 }
841 let mbox = MBox::from_raw_parts(slice_content, 3);
842 assert_eq!(mbox.len(), 3);
843
844 {
845 let cloned_mbox = mbox.clone();
846 counter.assert_eq(0);
847 assert_eq!(cloned_mbox.len(), 3);
848 cloned_mbox[0].assert_eq(0);
849 cloned_mbox[1].assert_eq(0);
850 cloned_mbox[2].assert_eq(0);
851 }
852
853 counter.assert_eq(3);
854 mbox[0].assert_eq(3);
855 mbox[1].assert_eq(3);
856 mbox[2].assert_eq(3);
857 }
858
859 counter.assert_eq(6);
860}
861
862#[cfg(not(windows))]
863#[test]
864fn test_from_iterator() {
865 let counter = DropCounter::default();
866 {
867 let slice = repeat(counter.clone()).take(18).collect::<MBox<[_]>>();
868 counter.assert_eq(1);
869 assert_eq!(slice.len(), 18);
870 for c in &slice {
871 c.assert_eq(1);
872 }
873 }
874 counter.assert_eq(19);
875}
876
877#[test]
878fn test_from_iterator_with_no_size_hint() {
879 struct RedactSizeHint<I>(I);
880
881 impl<I: Iterator> Iterator for RedactSizeHint<I> {
882 type Item = I::Item;
883
884 fn next(&mut self) -> Option<Self::Item> {
885 self.0.next()
886 }
887 }
888
889 let it = RedactSizeHint(b"1234567890".iter().copied());
890 assert_eq!(it.size_hint(), (0, None));
891 let slice = it.collect::<MBox<[u8]>>();
892 assert_eq!(&*slice, b"1234567890");
893}
894
895#[cfg(not(windows))]
896#[test]
897fn test_into_iterator() {
898 let counter = DropCounter::default();
899 {
900 let slice = repeat(counter.clone()).take(18).collect::<MBox<[_]>>();
901 counter.assert_eq(1);
902 assert_eq!(slice.len(), 18);
903 for (c, i) in slice.into_iter().zip(1..) {
904 c.assert_eq(i);
905 }
906 }
907 counter.assert_eq(19);
908}
909
910#[cfg(feature = "std")]
911#[test]
912fn test_iter_properties() {
913 let slice = vec![1i8, 4, 9, 16, 25].into_iter().collect::<MBox<[_]>>();
914 let mut iter = slice.into_iter();
915 assert_eq!(iter.size_hint(), (5, Some(5)));
916 assert_eq!(iter.len(), 5);
917 assert_eq!(iter.next(), Some(1));
918 assert_eq!(iter.next_back(), Some(25));
919 assert_eq!(iter.size_hint(), (3, Some(3)));
920 assert_eq!(iter.len(), 3);
921 assert_eq!(iter.collect::<Vec<_>>(), vec![4, 9, 16]);
922}
923
924#[cfg(not(windows))]
925#[test]
926fn test_iter_drop() {
927 let counter = DropCounter::default();
928 {
929 let slice = repeat(counter.clone()).take(18).collect::<MBox<[_]>>();
930 counter.assert_eq(1);
931 assert_eq!(slice.len(), 18);
932
933 let mut iter = slice.into_iter();
934 counter.assert_eq(1);
935 {
936 iter.next().unwrap().assert_eq(1)
937 };
938 {
939 iter.next().unwrap().assert_eq(2)
940 };
941 {
942 iter.next_back().unwrap().assert_eq(3)
943 };
944 counter.assert_eq(4);
945 }
946 counter.assert_eq(19);
947}
948
949#[test]
950fn test_zst_slice() {
951 let slice = repeat(()).take(7).collect::<MBox<[_]>>();
952 let _ = slice.clone();
953 slice.into_iter();
954}
955
956#[test]
957#[should_panic(expected = "panic on clone")]
958fn test_panic_during_clone() {
959 let mbox = MBox::<PanicOnClone>::default();
960 let _ = mbox.clone();
961}
962
963#[test]
964#[should_panic(expected = "panic on clone")]
965fn test_panic_during_clone_from() {
966 let mut mbox = MBox::<PanicOnClone>::default();
967 let other = MBox::default();
968 mbox.clone_from(&other);
969}
970
971impl MBox<str> {
976 pub unsafe fn from_raw_utf8_parts_unchecked(value: *mut u8, len: usize) -> MBox<str> {
984 Self::from_utf8_unchecked(MBox::from_raw_parts(value, len))
985 }
986
987 pub unsafe fn from_raw_utf8_parts(value: *mut u8, len: usize) -> Result<MBox<str>, Utf8Error> {
995 Self::from_utf8(MBox::from_raw_parts(value, len))
996 }
997
998 pub fn into_bytes(self) -> MBox<[u8]> {
1000 unsafe { MBox::from_raw(Self::into_raw(self) as *mut [u8]) }
1001 }
1002
1003 pub unsafe fn from_utf8_unchecked(bytes: MBox<[u8]>) -> MBox<str> {
1009 Self::from_raw(MBox::into_raw(bytes) as *mut str)
1010 }
1011
1012 pub fn from_utf8(bytes: MBox<[u8]>) -> Result<MBox<str>, Utf8Error> {
1015 from_utf8(&bytes)?;
1016 unsafe { Ok(Self::from_utf8_unchecked(bytes)) }
1017 }
1018}
1019
1020impl Default for MBox<str> {
1021 fn default() -> Self {
1022 unsafe { Self::from_raw_utf8_parts_unchecked(gen_malloc(0).as_ptr(), 0) }
1023 }
1024}
1025
1026impl Clone for MBox<str> {
1027 fn clone(&self) -> Self {
1028 Self::from(&**self)
1029 }
1030}
1031
1032impl From<&str> for MBox<str> {
1033 fn from(string: &str) -> Self {
1035 let len = string.len();
1036 let new_slice = gen_malloc(len).as_ptr();
1037 unsafe {
1040 copy_nonoverlapping(string.as_ptr(), new_slice, len);
1041 Self::from_raw_utf8_parts_unchecked(new_slice, len)
1042 }
1043 }
1044}
1045
1046#[test]
1047fn test_string_from_bytes() {
1048 let bytes = MBox::from_slice(b"abcdef\xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x89");
1049 let string = MBox::from_utf8(bytes).unwrap();
1050 assert_eq!(&*string, "abcdef一二三");
1051 assert_eq!(string, MBox::<str>::from("abcdef一二三"));
1052 let bytes = string.into_bytes();
1053 assert_eq!(&*bytes, b"abcdef\xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x89");
1054}
1055
1056#[test]
1057fn test_string_with_internal_nul() {
1058 let string = MBox::<str>::from("ab\0c");
1059 assert_eq!(&*string, "ab\0c");
1060}
1061
1062#[test]
1063fn test_non_utf8() {
1064 let bytes = MBox::from_slice(b"\x88\x88\x88\x88");
1065 let string = MBox::from_utf8(bytes);
1066 assert!(string.is_err());
1067}
1068
1069#[test]
1070fn test_default_str() {
1071 assert_eq!(MBox::<str>::default(), MBox::<str>::from(""));
1072}
1073
1074#[test]
1075#[should_panic(expected = "panic on clone")]
1076fn test_panic_on_clone_slice() {
1077 let mbox: MBox<[PanicOnClone]> = once(PanicOnClone::default()).collect();
1078 let _ = mbox.clone();
1079}
1080
1081