1use std::{
4 borrow::{Borrow, BorrowMut},
5 error::Error as StdError,
6 future::Future,
7 hash::Hasher,
8 io::{self, BufRead, IoSlice, IoSliceMut, Read, Seek, Write},
9 iter::FusedIterator,
10 marker::{PhantomData, Unpin},
11 mem::ManuallyDrop,
12 ops::DerefMut,
13 pin::Pin,
14 ptr::{self, NonNull},
15 task::{Context, Poll},
16};
17
18#[allow(unused_imports)]
19use core_extensions::SelfOps;
20
21use crate::{
22 marker_type::NonOwningPhantom,
23 pointer_trait::{
24 AsMutPtr, AsPtr, CallReferentDrop, CanTransmuteElement, Deallocate, GetPointerKind,
25 OwnedPointer, PK_SmartPointer,
26 },
27 prefix_type::WithMetadata,
28 sabi_types::MovePtr,
29 std_types::utypeid::{new_utypeid, UTypeId},
30 traits::IntoReprRust,
31};
32
33#[cfg(all(test, not(feature = "only_new_tests")))]
35mod test;
36
37mod private {
38 use super::*;
39
40 #[repr(C)]
75 #[derive(StableAbi)]
76 pub struct RBox<T> {
77 data: NonNull<T>,
78 vtable: BoxVtable_Ref<T>,
79 _marker: PhantomData<T>,
80 }
81
82 impl<T> RBox<T> {
83 pub fn new(value: T) -> Self {
95 Box::new(value).piped(RBox::from_box)
96 }
97
98 pub fn pin(value: T) -> Pin<RBox<T>> {
101 RBox::new(value).into_pin()
102 }
103
104 pub fn from_box(p: Box<T>) -> RBox<T> {
117 RBox {
118 data: unsafe { NonNull::new_unchecked(Box::into_raw(p)) },
119 vtable: VTableGetter::<T>::LIB_VTABLE,
120 _marker: PhantomData,
121 }
122 }
123
124 pub fn from_move_ptr(p: MovePtr<'_, T>) -> RBox<T> {
144 MovePtr::into_rbox(p)
145 }
146
147 #[inline(always)]
148 pub(super) const fn data(&self) -> *mut T {
149 self.data.as_ptr()
150 }
151 #[inline(always)]
152 pub(super) fn data_mut(&mut self) -> *mut T {
153 self.data.as_ptr()
154 }
155
156 #[inline(always)]
157 pub(super) const fn vtable(&self) -> BoxVtable_Ref<T> {
158 self.vtable
159 }
160
161 #[allow(dead_code)]
162 #[cfg(test)]
163 pub(super) fn set_vtable_for_testing(&mut self) {
164 self.vtable = VTableGetter::<T>::LIB_VTABLE_FOR_TESTING;
165 }
166 }
167
168 unsafe impl<T> AsPtr for RBox<T> {
169 #[inline(always)]
170 fn as_ptr(&self) -> *const T {
171 self.data.as_ptr()
172 }
173 }
174 unsafe impl<T> AsMutPtr for RBox<T> {
175 #[inline(always)]
176 fn as_mut_ptr(&mut self) -> *mut T {
177 self.data.as_ptr()
178 }
179 }
180}
181
182pub use self::private::RBox;
183
184unsafe impl<T> GetPointerKind for RBox<T> {
185 type Kind = PK_SmartPointer;
186
187 type PtrTarget = T;
188}
189
190unsafe impl<T, O> CanTransmuteElement<O> for RBox<T> {
191 type TransmutedPtr = RBox<O>;
192
193 unsafe fn transmute_element_(self) -> Self::TransmutedPtr {
194 unsafe { core_extensions::utils::transmute_ignore_size(self) }
195 }
196}
197
198impl<T> RBox<T> {
199 pub fn into_box(this: Self) -> Box<T> {
217 let this = ManuallyDrop::new(this);
218
219 unsafe {
220 let this_vtable = this.vtable();
221 let other_vtable = VTableGetter::LIB_VTABLE;
222 if ::std::ptr::eq(this_vtable.0.to_raw_ptr(), other_vtable.0.to_raw_ptr())
223 || this_vtable.type_id()() == other_vtable.type_id()()
224 {
225 Box::from_raw(this.data())
226 } else {
227 let ret = Box::new(this.data().read());
228 (this.vtable().destructor())(
230 this.data() as *mut (),
231 CallReferentDrop::No,
232 Deallocate::Yes,
233 );
234 ret
235 }
236 }
237 }
238
239 pub fn into_inner(this: Self) -> T {
252 unsafe {
253 let value = this.data().read();
254 Self::drop_allocation(&mut ManuallyDrop::new(this));
255 value
256 }
257 }
258
259 pub fn into_pin(self) -> Pin<RBox<T>> {
262 unsafe { Pin::new_unchecked(self) }
264 }
265}
266
267impl<T> DerefMut for RBox<T> {
268 fn deref_mut(&mut self) -> &mut Self::Target {
269 unsafe { &mut *self.data() }
270 }
271}
272
273unsafe impl<T> OwnedPointer for RBox<T> {
276 #[inline]
277 unsafe fn get_move_ptr(this: &mut ManuallyDrop<Self>) -> MovePtr<'_, T> {
278 unsafe { MovePtr::from_raw(this.data_mut()) }
279 }
280
281 #[inline]
282 unsafe fn drop_allocation(this: &mut ManuallyDrop<Self>) {
283 let data: *mut T = this.data();
284 unsafe {
285 (this.vtable().destructor())(data as *mut (), CallReferentDrop::No, Deallocate::Yes);
286 }
287 }
288}
289
290impl<T> Borrow<T> for RBox<T> {
293 fn borrow(&self) -> &T {
294 self
295 }
296}
297
298impl<T> BorrowMut<T> for RBox<T> {
299 fn borrow_mut(&mut self) -> &mut T {
300 self
301 }
302}
303
304impl<T> AsRef<T> for RBox<T> {
305 fn as_ref(&self) -> &T {
306 self
307 }
308}
309
310impl<T> AsMut<T> for RBox<T> {
311 fn as_mut(&mut self) -> &mut T {
312 self
313 }
314}
315
316impl_from_rust_repr! {
319 impl[T] From<Box<T>> for RBox<T> {
320 fn(this){
321 RBox::from_box(this)
322 }
323 }
324}
325
326impl<T> From<RBox<T>> for Pin<RBox<T>> {
327 fn from(boxed: RBox<T>) -> Pin<RBox<T>> {
328 boxed.into_pin()
329 }
330}
331
332impl<T> IntoReprRust for RBox<T> {
335 type ReprRust = Box<T>;
336
337 fn into_rust(self) -> Self::ReprRust {
338 Self::into_box(self)
339 }
340}
341
342impl<T> Default for RBox<T>
345where
346 T: Default,
347{
348 fn default() -> Self {
349 Self::new(T::default())
350 }
351}
352
353impl<T> Clone for RBox<T>
354where
355 T: Clone,
356{
357 fn clone(&self) -> Self {
358 (**self).clone().piped(Box::new).into()
359 }
360}
361
362shared_impls! {pointer
363 mod = box_impls
364 new_type = RBox[][T],
365 original_type = Box,
366}
367
368unsafe impl<T: Send> Send for RBox<T> {}
369unsafe impl<T: Sync> Sync for RBox<T> {}
370impl<T> Unpin for RBox<T> {}
371
372impl<I> Iterator for RBox<I>
375where
376 I: Iterator,
377{
378 type Item = I::Item;
379 fn next(&mut self) -> Option<I::Item> {
380 (**self).next()
381 }
382 fn size_hint(&self) -> (usize, Option<usize>) {
383 (**self).size_hint()
384 }
385 fn nth(&mut self, n: usize) -> Option<I::Item> {
386 (**self).nth(n)
387 }
388 fn last(self) -> Option<I::Item> {
389 RBox::into_inner(self).last()
390 }
391}
392
393impl<I> DoubleEndedIterator for RBox<I>
394where
395 I: DoubleEndedIterator,
396{
397 fn next_back(&mut self) -> Option<I::Item> {
398 (**self).next_back()
399 }
400 fn nth_back(&mut self, n: usize) -> Option<I::Item> {
401 (**self).nth_back(n)
402 }
403}
404
405impl<I> ExactSizeIterator for RBox<I>
406where
407 I: ExactSizeIterator,
408{
409 fn len(&self) -> usize {
410 (**self).len()
411 }
412}
413
414impl<I> FusedIterator for RBox<I> where I: FusedIterator {}
415
416impl<F> Future for RBox<F>
419where
420 F: Future + Unpin,
421{
422 type Output = F::Output;
423
424 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
425 F::poll(Pin::new(&mut *self), cx)
426 }
427}
428
429impl<T> StdError for RBox<T>
432where
433 T: StdError,
434{
435 #[allow(deprecated, deprecated_in_future)]
436 fn description(&self) -> &str {
437 StdError::description(&**self)
438 }
439
440 #[allow(deprecated)]
441 fn cause(&self) -> Option<&dyn StdError> {
442 StdError::cause(&**self)
443 }
444
445 fn source(&self) -> Option<&(dyn StdError + 'static)> {
446 StdError::source(&**self)
447 }
448}
449
450impl<T> Read for RBox<T>
453where
454 T: Read,
455{
456 #[inline]
457 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
458 (**self).read(buf)
459 }
460
461 #[inline]
462 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
463 (**self).read_vectored(bufs)
464 }
465
466 #[inline]
467 fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
468 (**self).read_to_end(buf)
469 }
470
471 #[inline]
472 fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
473 (**self).read_to_string(buf)
474 }
475
476 #[inline]
477 fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
478 (**self).read_exact(buf)
479 }
480}
481
482impl<T> Write for RBox<T>
483where
484 T: Write,
485{
486 #[inline]
487 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
488 (**self).write(buf)
489 }
490
491 #[inline]
492 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
493 (**self).write_vectored(bufs)
494 }
495
496 #[inline]
497 fn flush(&mut self) -> io::Result<()> {
498 (**self).flush()
499 }
500
501 #[inline]
502 fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
503 (**self).write_all(buf)
504 }
505
506 #[inline]
507 fn write_fmt(&mut self, fmt: std::fmt::Arguments<'_>) -> io::Result<()> {
508 (**self).write_fmt(fmt)
509 }
510}
511
512impl<T> Seek for RBox<T>
513where
514 T: Seek,
515{
516 #[inline]
517 fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
518 (**self).seek(pos)
519 }
520}
521
522impl<T> BufRead for RBox<T>
523where
524 T: BufRead,
525{
526 #[inline]
527 fn fill_buf(&mut self) -> io::Result<&[u8]> {
528 (**self).fill_buf()
529 }
530
531 #[inline]
532 fn consume(&mut self, amt: usize) {
533 (**self).consume(amt)
534 }
535
536 #[inline]
537 fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<usize> {
538 (**self).read_until(byte, buf)
539 }
540
541 #[inline]
542 fn read_line(&mut self, buf: &mut String) -> io::Result<usize> {
543 (**self).read_line(buf)
544 }
545}
546
547impl<T> Hasher for RBox<T>
550where
551 T: Hasher,
552{
553 fn finish(&self) -> u64 {
554 (**self).finish()
555 }
556 fn write(&mut self, bytes: &[u8]) {
557 (**self).write(bytes)
558 }
559 fn write_u8(&mut self, i: u8) {
560 (**self).write_u8(i)
561 }
562 fn write_u16(&mut self, i: u16) {
563 (**self).write_u16(i)
564 }
565 fn write_u32(&mut self, i: u32) {
566 (**self).write_u32(i)
567 }
568 fn write_u64(&mut self, i: u64) {
569 (**self).write_u64(i)
570 }
571 fn write_u128(&mut self, i: u128) {
572 (**self).write_u128(i)
573 }
574 fn write_usize(&mut self, i: usize) {
575 (**self).write_usize(i)
576 }
577 fn write_i8(&mut self, i: i8) {
578 (**self).write_i8(i)
579 }
580 fn write_i16(&mut self, i: i16) {
581 (**self).write_i16(i)
582 }
583 fn write_i32(&mut self, i: i32) {
584 (**self).write_i32(i)
585 }
586 fn write_i64(&mut self, i: i64) {
587 (**self).write_i64(i)
588 }
589 fn write_i128(&mut self, i: i128) {
590 (**self).write_i128(i)
591 }
592 fn write_isize(&mut self, i: isize) {
593 (**self).write_isize(i)
594 }
595}
596
597impl<T> Drop for RBox<T> {
600 fn drop(&mut self) {
601 unsafe {
602 let data = self.data();
603 let dstr = RBox::vtable(self).destructor();
604 dstr(data as *mut (), CallReferentDrop::Yes, Deallocate::Yes);
605 }
606 }
607}
608
609#[derive(StableAbi)]
612#[repr(C)]
613#[sabi(kind(Prefix))]
614#[sabi(missing_field(panic))]
615pub(crate) struct BoxVtable<T> {
616 type_id: extern "C" fn() -> UTypeId,
617 #[sabi(last_prefix_field)]
618 destructor: unsafe extern "C" fn(*mut (), CallReferentDrop, Deallocate),
619 _marker: NonOwningPhantom<T>,
620}
621
622struct VTableGetter<'a, T>(&'a T);
623
624impl<'a, T: 'a> VTableGetter<'a, T> {
625 const DEFAULT_VTABLE: BoxVtable<T> = BoxVtable {
626 type_id: new_utypeid::<RBox<()>>,
627 destructor: destroy_box::<T>,
628 _marker: NonOwningPhantom::NEW,
629 };
630
631 staticref! {
632 const WM_DEFAULT: WithMetadata<BoxVtable<T>> = WithMetadata::new(Self::DEFAULT_VTABLE);
633 }
634
635 const LIB_VTABLE: BoxVtable_Ref<T> = BoxVtable_Ref(Self::WM_DEFAULT.as_prefix());
637
638 #[cfg(test)]
639 staticref! {
640 const WM_FOR_TESTING: WithMetadata<BoxVtable<T>> =
641 WithMetadata::new(
642 BoxVtable {
643 type_id: new_utypeid::<RBox<i32>>,
644 ..Self::DEFAULT_VTABLE
645 },
646 )
647 }
648
649 #[allow(dead_code)]
650 #[cfg(test)]
651 const LIB_VTABLE_FOR_TESTING: BoxVtable_Ref<T> =
652 BoxVtable_Ref(Self::WM_FOR_TESTING.as_prefix());
653}
654
655unsafe extern "C" fn destroy_box<T>(
656 ptr: *mut (),
657 call_drop: CallReferentDrop,
658 dealloc: Deallocate,
659) {
660 extern_fn_panic_handling! {no_early_return;
661 let ptr = ptr as *mut T;
662 if let CallReferentDrop::Yes = call_drop {
663 unsafe { ptr::drop_in_place(ptr); }
664 }
665 if let Deallocate::Yes = dealloc {
666 unsafe { drop(Box::from_raw(ptr as *mut ManuallyDrop<T>)); }
667 }
668 }
669}
670
671