1use core::borrow;
4use core::cmp::Ordering;
5use core::mem::{ManuallyDrop, MaybeUninit};
6use core::ops::{Deref, DerefMut};
7use core::ptr::NonNull;
8use core::str;
9use core::{fmt, ptr};
10
11#[cfg(feature = "zeroize")]
12use zeroize::{Zeroize, ZeroizeOnDrop};
13
14use crate::alloc::{AllocateIn, Allocator, AllocatorDefault, Global};
15use crate::storage::boxed::RawBox;
16use crate::vec::config::VecConfigAlloc;
17use crate::vec::Vec;
18use crate::StorageError;
19
20#[cfg(feature = "alloc")]
21use crate::alloc::ConvertAlloc;
22
23pub struct Box<T: ?Sized, A: Allocator = Global> {
25 pub(crate) handle: RawBox<T, A>,
26}
27
28impl<T, A: AllocatorDefault> Box<T, A> {
29 pub fn new(value: T) -> Box<T, A> {
32 match Self::try_new(value) {
33 Ok(slf) => slf,
34 Err(e) => e.panic(),
35 }
36 }
37
38 pub fn new_uninit() -> Box<MaybeUninit<T>, A> {
41 match Self::try_new_uninit() {
42 Ok(uninit) => uninit,
43 Err(e) => e.panic(),
44 }
45 }
46
47 pub fn try_new(value: T) -> Result<Box<T, A>, StorageError> {
50 RawBox::alloc().map(|boxed| Self {
51 handle: boxed.write(value),
52 })
53 }
54
55 pub fn try_new_uninit() -> Result<Box<MaybeUninit<T>, A>, StorageError> {
58 RawBox::alloc().map(|inner| Box { handle: inner })
59 }
60
61 pub fn into_inner(boxed: Self) -> T {
63 boxed.into_handle().into_inner()
64 }
65}
66
67impl<T, A: AllocatorDefault> Box<[T], A> {
68 pub fn new_uninit_slice(len: usize) -> Box<[MaybeUninit<T>], A> {
71 match Self::try_new_uninit_slice(len) {
72 Ok(res) => res,
73 Err(err) => err.panic(),
74 }
75 }
76
77 pub fn try_new_uninit_slice(len: usize) -> Result<Box<[MaybeUninit<T>], A>, StorageError> {
80 RawBox::alloc_slice(len, true).map(|inner| Box { handle: inner })
81 }
82}
83
84impl<T: ?Sized, A: AllocatorDefault> Box<T, A> {
85 pub unsafe fn from_raw(raw: *mut T) -> Self {
94 Self::from_raw_in(raw, A::DEFAULT)
95 }
96
97 pub fn into_raw(boxed: Self) -> *mut T {
112 Self::into_raw_with_allocator(boxed).0
113 }
114}
115
116impl<T, A: Allocator> Box<T, A> {
117 pub fn new_in<I>(value: T, alloc_in: I) -> Box<T, A>
120 where
121 I: AllocateIn<Alloc = A>,
122 {
123 match Self::try_new_in(value, alloc_in) {
124 Ok(slf) => slf,
125 Err(e) => e.panic(),
126 }
127 }
128
129 pub fn new_uninit_in<I>(alloc_in: I) -> Box<MaybeUninit<T>, A>
132 where
133 I: AllocateIn<Alloc = A>,
134 {
135 match Self::try_new_uninit_in(alloc_in) {
136 Ok(uninit) => uninit,
137 Err(e) => e.panic(),
138 }
139 }
140
141 pub fn try_new_in<I>(value: T, alloc_in: I) -> Result<Box<T, A>, StorageError>
144 where
145 I: AllocateIn<Alloc = A>,
146 {
147 RawBox::alloc_in(alloc_in).map(|boxed| Self {
148 handle: boxed.write(value),
149 })
150 }
151
152 pub fn try_new_uninit_in<I>(alloc_in: I) -> Result<Box<MaybeUninit<T>, A>, StorageError>
155 where
156 I: AllocateIn<Alloc = A>,
157 {
158 RawBox::alloc_in(alloc_in).map(|inner| Box { handle: inner })
159 }
160}
161
162impl<T, A: Allocator> Box<[T], A> {
163 pub fn new_uninit_slice_in<I>(len: usize, alloc_in: I) -> Box<[MaybeUninit<T>], A>
166 where
167 I: AllocateIn<Alloc = A>,
168 {
169 match Self::try_new_uninit_slice_in(len, alloc_in) {
170 Ok(res) => res,
171 Err(err) => err.panic(),
172 }
173 }
174
175 pub fn try_new_uninit_slice_in<I>(
178 len: usize,
179 alloc_in: I,
180 ) -> Result<Box<[MaybeUninit<T>], A>, StorageError>
181 where
182 I: AllocateIn<Alloc = A>,
183 {
184 RawBox::alloc_slice_in(alloc_in, len, true).map(|inner| Box { handle: inner })
185 }
186
187 pub fn into_vec(self) -> Vec<T, A> {
189 let (ptr, alloc) = self.into_handle().into_parts();
190 let len = ptr.len();
191 unsafe { Vec::from_parts(ptr.cast::<T>(), len, len, alloc) }
194 }
195
196 fn dangling(alloc: A) -> Box<[T], A> {
197 Self {
198 handle: RawBox::dangling(alloc),
199 }
200 }
201}
202
203impl<A: Allocator> Box<str, A> {
204 pub fn from_utf8(boxed: Box<[u8], A>) -> Result<Self, str::Utf8Error> {
211 let (ptr, alloc) = Box::into_raw_with_allocator(boxed);
212 unsafe {
213 let strval = str::from_utf8_mut(&mut *ptr)?;
215 Ok(Self::from_raw_in(strval, alloc))
218 }
219 }
220
221 pub unsafe fn from_utf8_unchecked(boxed: Box<[u8], A>) -> Self {
226 let (ptr, alloc) = Box::into_raw_with_allocator(boxed);
227 let strval = str::from_utf8_unchecked_mut(&mut *ptr);
229 Self::from_raw_in(strval, alloc)
232 }
233}
234
235impl<T: Clone, A: AllocatorDefault> Box<[T], A> {
236 pub fn from_slice(data: &[T]) -> Self {
238 match Self::try_from_slice(data) {
239 Ok(res) => res,
240 Err(err) => err.panic(),
241 }
242 }
243
244 pub fn try_from_slice(data: &[T]) -> Result<Self, StorageError> {
246 let len = data.len();
247 let handle = RawBox::alloc_slice(len, true)?;
248 Ok(Self {
249 handle: handle.write_slice(|insert| {
250 insert.push_slice(data);
251 }),
252 })
253 }
254}
255
256impl<T: Clone, A: Allocator> Box<[T], A> {
257 pub fn from_slice_in<I>(data: &[T], alloc_in: I) -> Self
259 where
260 I: AllocateIn<Alloc = A>,
261 {
262 match Self::try_from_slice_in(data, alloc_in) {
263 Ok(res) => res,
264 Err(err) => err.panic(),
265 }
266 }
267
268 pub fn try_from_slice_in<I>(data: &[T], alloc_in: I) -> Result<Self, StorageError>
270 where
271 I: AllocateIn<Alloc = A>,
272 {
273 let len = data.len();
274 let handle = RawBox::alloc_slice_in(alloc_in, len, true)?;
275 Ok(Self {
276 handle: handle.write_slice(|insert| {
277 insert.push_slice(data);
278 }),
279 })
280 }
281}
282
283impl<T: ?Sized, A: Allocator> Box<T, A> {
284 pub fn allocator(&self) -> &A {
286 self.handle.allocator()
287 }
288
289 #[inline]
292 pub fn as_ptr(&self) -> *const T {
293 self.handle.as_ptr()
294 }
295
296 #[inline]
299 pub fn as_mut_ptr(&mut self) -> *mut T {
300 self.handle.as_mut_ptr()
301 }
302
303 pub unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self {
312 let ptr = NonNull::new(raw).expect("from_raw: pointer must not be null");
313 Self {
314 handle: RawBox::from_parts(ptr, alloc),
315 }
316 }
317
318 pub fn into_raw_with_allocator(boxed: Self) -> (*mut T, A) {
333 let (ptr, alloc) = boxed.into_handle().into_parts();
334 (ptr.as_ptr(), alloc)
335 }
336
337 pub fn leak<'a>(boxed: Self) -> &'a mut T
352 where
353 A: 'a,
354 {
355 boxed.into_handle().leak()
356 }
357
358 #[inline]
359 pub(crate) fn into_handle(self) -> RawBox<T, A> {
360 unsafe { ptr::read(&ManuallyDrop::new(self).handle) }
365 }
366}
367
368impl<T, A: Allocator> Box<MaybeUninit<T>, A> {
369 #[inline]
375 pub unsafe fn assume_init(self) -> Box<T, A> {
376 Box {
377 handle: self.into_handle().assume_init(),
378 }
379 }
380
381 #[inline(always)]
388 pub fn write(boxed: Self, value: T) -> Box<T, A> {
389 Box {
390 handle: boxed.into_handle().write(value),
391 }
392 }
393}
394
395impl<T, A: Allocator> Box<[MaybeUninit<T>], A> {
396 #[inline]
402 pub unsafe fn assume_init(self) -> Box<[T], A> {
403 Box {
404 handle: self.into_handle().assume_init(),
405 }
406 }
407}
408
409impl<T, A: Allocator, const N: usize> Box<[T; N], A> {
410 pub fn into_boxed_slice(boxed: Self) -> Box<[T], A> {
414 let (ptr, alloc) = boxed.into_handle().into_parts();
415 Box {
416 handle: RawBox::from_parts(NonNull::slice_from_raw_parts(ptr.cast::<T>(), N), alloc),
417 }
418 }
419}
420
421impl<T: ?Sized, A: Allocator> AsRef<T> for Box<T, A> {
422 fn as_ref(&self) -> &T {
423 self.handle.as_ref()
424 }
425}
426
427impl<T: ?Sized, A: Allocator> AsMut<T> for Box<T, A> {
428 fn as_mut(&mut self) -> &mut T {
429 self.handle.as_mut()
430 }
431}
432
433impl<T: ?Sized, A: Allocator> borrow::Borrow<T> for Box<T, A> {
434 fn borrow(&self) -> &T {
435 self.handle.as_ref()
436 }
437}
438
439impl<T: ?Sized, A: Allocator> borrow::BorrowMut<T> for Box<T, A> {
440 fn borrow_mut(&mut self) -> &mut T {
441 self.handle.as_mut()
442 }
443}
444
445impl<T: Clone, A: Allocator + Clone> Clone for Box<T, A> {
446 fn clone(&self) -> Self {
447 let boxed = Self::new_uninit_in(self.allocator().clone());
448 Box::write(boxed, self.as_ref().clone())
449 }
450}
451
452impl<T: Clone, A: Allocator + Clone> Clone for Box<[T], A> {
453 fn clone(&self) -> Self {
454 Self::from_slice_in(self.as_ref(), self.allocator().clone())
455 }
456}
457
458impl<A: Allocator + Clone> Clone for Box<str, A> {
459 fn clone(&self) -> Self {
460 let boxed = Box::<[u8], A>::from_slice_in(self.as_bytes(), self.allocator().clone());
461 unsafe { Box::from_utf8_unchecked(boxed) }
463 }
464}
465
466#[cfg(feature = "nightly")]
467impl<T: ?Sized + core::marker::Unsize<U>, U: ?Sized, A: Allocator>
468 core::ops::CoerceUnsized<Box<U, A>> for Box<T, A>
469{
470}
471
472impl<T: ?Sized + fmt::Debug, A: Allocator> fmt::Debug for Box<T, A> {
473 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
474 self.as_ref().fmt(f)
475 }
476}
477
478impl<T: Default, A: AllocatorDefault> Default for Box<T, A> {
479 fn default() -> Self {
480 Self::new(T::default())
481 }
482}
483
484impl<T, A: AllocatorDefault> Default for Box<[T], A> {
485 fn default() -> Self {
486 Self::dangling(A::DEFAULT)
487 }
488}
489
490impl<A: AllocatorDefault> Default for Box<str, A> {
491 fn default() -> Self {
492 unsafe { Box::from_utf8_unchecked(Box::dangling(A::DEFAULT)) }
494 }
495}
496
497impl<T: ?Sized, A: Allocator> Deref for Box<T, A> {
498 type Target = T;
499
500 fn deref(&self) -> &Self::Target {
501 self.handle.as_ref()
502 }
503}
504
505impl<T: ?Sized, A: Allocator> DerefMut for Box<T, A> {
506 fn deref_mut(&mut self) -> &mut Self::Target {
507 self.handle.as_mut()
508 }
509}
510
511impl<T: ?Sized, A: Allocator> Drop for Box<T, A> {
512 fn drop(&mut self) {
513 unsafe {
514 ptr::drop_in_place(self.handle.as_mut());
515 }
516 }
517}
518
519impl<T, A: AllocatorDefault> From<T> for Box<T, A> {
520 #[inline]
521 fn from(value: T) -> Self {
522 Box::write(Self::new_uninit(), value)
523 }
524}
525
526impl<T: Clone, A: AllocatorDefault> From<&[T]> for Box<[T], A> {
527 fn from(data: &[T]) -> Self {
528 Self::from_slice(data)
529 }
530}
531
532impl<T, A: AllocatorDefault, const N: usize> From<[T; N]> for Box<[T], A> {
533 fn from(data: [T; N]) -> Self {
534 Box::into_boxed_slice(Box::new(data))
535 }
536}
537
538impl<A: AllocatorDefault> From<&str> for Box<str, A> {
539 fn from(data: &str) -> Self {
540 let boxed = Box::from_slice(data.as_bytes());
541 unsafe { Self::from_utf8_unchecked(boxed) }
543 }
544}
545
546impl<T, C> From<Vec<T, C>> for Box<[T], C::Alloc>
547where
548 C: VecConfigAlloc<T>,
549{
550 fn from(vec: Vec<T, C>) -> Self {
551 vec.into_boxed_slice()
552 }
553}
554
555impl<T, A: AllocatorDefault> FromIterator<T> for Box<[T], A> {
556 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
557 Vec::<T, A>::from_iter(iter).into_boxed_slice()
558 }
559}
560
561impl<T, A: Allocator, const N: usize> TryFrom<Box<[T], A>> for Box<[T; N], A> {
562 type Error = Box<[T], A>;
563
564 fn try_from(boxed: Box<[T], A>) -> Result<Self, Self::Error> {
565 if boxed.len() == N {
566 Ok(Self {
567 handle: unsafe { boxed.into_handle().cast() },
568 })
569 } else {
570 Err(boxed)
571 }
572 }
573}
574
575impl<T, A: Allocator, const N: usize> TryFrom<Vec<T, A>> for Box<[T; N], A> {
576 type Error = Vec<T, A>;
577
578 fn try_from(vec: Vec<T, A>) -> Result<Self, Self::Error> {
579 if vec.len() == N {
580 let boxed = vec.into_boxed_slice();
581 Ok(Self {
582 handle: unsafe { boxed.into_handle().cast() },
583 })
584 } else {
585 Err(vec)
586 }
587 }
588}
589
590#[cfg(all(feature = "alloc", not(feature = "nightly")))]
591impl<T: ?Sized> ConvertAlloc<Box<T, Global>> for alloc_crate::boxed::Box<T> {
592 fn convert(self) -> Box<T, Global> {
593 let raw = alloc_crate::boxed::Box::into_raw(self);
594 unsafe { Box::from_raw(raw) }
595 }
596}
597
598#[cfg(all(feature = "alloc", feature = "nightly"))]
599impl<T: ?Sized, A: Allocator> ConvertAlloc<Box<T, A>> for alloc_crate::boxed::Box<T, A> {
600 fn convert(self) -> Box<T, A> {
601 let (raw, alloc) = alloc_crate::boxed::Box::into_raw_with_allocator(self);
602 unsafe { Box::from_raw_in(raw, alloc) }
603 }
604}
605
606#[cfg(all(feature = "alloc", not(feature = "nightly")))]
607impl<T: ?Sized> ConvertAlloc<alloc_crate::boxed::Box<T>> for Box<T, Global> {
608 fn convert(self) -> alloc_crate::boxed::Box<T> {
609 let raw = Box::into_raw(self);
610 unsafe { alloc_crate::boxed::Box::from_raw(raw) }
611 }
612}
613
614#[cfg(all(feature = "alloc", feature = "nightly"))]
615impl<T: ?Sized, A: Allocator> ConvertAlloc<alloc_crate::boxed::Box<T, A>> for Box<T, A> {
616 fn convert(self) -> alloc_crate::boxed::Box<T, A> {
617 let (raw, alloc) = Box::into_raw_with_allocator(self);
618 unsafe { alloc_crate::boxed::Box::from_raw_in(raw, alloc) }
619 }
620}
621
622impl<T: ?Sized + PartialEq, A: Allocator> PartialEq for Box<T, A> {
623 #[inline]
624 fn eq(&self, other: &Self) -> bool {
625 PartialEq::eq(self.as_ref(), other.as_ref())
626 }
627}
628
629impl<T: ?Sized + Eq, A: Allocator> Eq for Box<T, A> {}
630
631impl<T: ?Sized + PartialOrd, A: Allocator> PartialOrd for Box<T, A> {
632 #[inline]
633 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
634 PartialOrd::partial_cmp(&**self, &**other)
635 }
636}
637
638impl<T: ?Sized + Ord, A: Allocator> Ord for Box<T, A> {
639 #[inline]
640 fn cmp(&self, other: &Self) -> Ordering {
641 Ord::cmp(&**self, &**other)
642 }
643}
644
645unsafe impl<T: Send + ?Sized, A: Allocator + Send> Send for Box<T, A> {}
646unsafe impl<T: Sync + ?Sized, A: Allocator + Sync> Sync for Box<T, A> {}
647
648impl<T: ?Sized, A: Allocator> Unpin for Box<T, A> {}
649
650#[cfg(feature = "zeroize")]
651impl<T: ?Sized + Zeroize, A: Allocator> Zeroize for Box<T, A> {
652 fn zeroize(&mut self) {
653 self.as_mut().zeroize()
654 }
655}
656
657#[cfg(feature = "zeroize")]
658impl<T: ?Sized, A: crate::alloc::AllocatorZeroizes> ZeroizeOnDrop for Box<T, A> {}
659
660#[cfg(test)]
661mod tests {
662 #[cfg(all(feature = "alloc", feature = "nightly"))]
663 #[test]
664 fn box_unsized() {
665 use core::any::Any;
666
667 use super::Box;
668
669 let _ = Box::new(10usize) as Box<dyn Any>;
670 }
671}