Struct abi_stable::sabi_types::MovePtr
source · pub struct MovePtr<'a, T> { /* private fields */ }
Expand description
A move pointer, which allows moving the value from the reference, consuming it in the process.
If MovePtr::into_inner
isn’t called, this drops the referenced value when it’s dropped
§Safety
This is unsafe to construct since the user must ensure that the original owner of the value never accesses it again.
§Motivation
MovePtr
was created as a way to pass self
by value to ffi-safe trait object methods,
since one can’t simply pass self
by value(because the type is erased).
§Examples
§Using OwnedPointer::in_move_ptr
This is how one can use MovePtr without unsafe
.
This simply moves the contents of an RBox<T>
into a Box<T>
.
use abi_stable::{
pointer_trait::OwnedPointer, sabi_types::MovePtr, std_types::RBox,
};
fn move_rbox_to_box<T>(rbox: RBox<T>) -> Box<T> {
rbox.in_move_ptr(|move_ptr| MovePtr::into_box(move_ptr))
}
assert_eq!(move_rbox_to_box(RBox::new(99)), Box::new(99));
assert_eq!(move_rbox_to_box(RBox::new(())), Box::new(()));
assert_eq!(
move_rbox_to_box(RBox::new(String::from("SHIT"))),
Box::new(String::from("SHIT"))
);
§Using the (unsafe) MovePtr::new
This is (sort of) how RBox<T>
implements moving the T
it owns out of its allocation
This is basically what OwnedPointer::{with_move_ptr,in_move_ptr}
do.
use abi_stable::{
pointer_trait::{AsMutPtr, OwnedPointer},
sabi_types::MovePtr,
std_types::RBox,
};
use std::mem::ManuallyDrop;
let rbox = RBox::new(0x100);
let second_rbox;
unsafe {
let mut rbox = ManuallyDrop::new(rbox);
let move_ptr = unsafe { MovePtr::from_rmut(rbox.as_rmut()) };
second_rbox = RBox::from_move_ptr(move_ptr);
OwnedPointer::drop_allocation(&mut rbox);
}
assert_eq!(second_rbox, RBox::new(0x100));
Implementations§
source§impl<'a, T> MovePtr<'a, T>
impl<'a, T> MovePtr<'a, T>
sourcepub unsafe fn new(ptr: &'a mut T) -> Self
pub unsafe fn new(ptr: &'a mut T) -> Self
Constructs this move pointer from a mutable reference, moving the value out of the reference.
§Safety
Callers must ensure that the original owner of the value won’t access the moved-out value anymore.
§Example
use abi_stable::sabi_types::MovePtr;
use std::mem::ManuallyDrop;
let mut manual = ManuallyDrop::new(String::from("hello"));
let moveptr = unsafe { MovePtr::new(&mut *manual) };
drop(moveptr); // moveptr drops the String here.
sourcepub const unsafe fn from_rmut(ptr: RMut<'a, T>) -> Self
pub const unsafe fn from_rmut(ptr: RMut<'a, T>) -> Self
Constructs this move pointer from an RMut
,
moving the value out of the reference.
§Safety
Callers must ensure that the original owner of the value won’t access the moved-out value anymore.
§Example
use abi_stable::{
pointer_trait::AsMutPtr, sabi_types::MovePtr, std_types::RString,
utils::manuallydrop_as_rmut,
};
use std::mem::ManuallyDrop;
let mut mdrop = ManuallyDrop::new(RString::from("hello"));
// safety: `mdrop` is never accessed again
let moveptr = unsafe { MovePtr::from_rmut(manuallydrop_as_rmut(&mut mdrop)) };
assert_eq!(*moveptr, "hello");
let string: RString = MovePtr::into_inner(moveptr);
assert_eq!(string, "hello");
sourcepub const unsafe fn from_raw(ptr: *mut T) -> Self
pub const unsafe fn from_raw(ptr: *mut T) -> Self
Constructs this move pointer from a raw pointer, moving the value out of it.
§Safety
Callers must ensure that the original owner of the value won’t access the moved-out value anymore.
Because this takes a mutable pointer, the lifetime of this MovePtr
is unbounded.
You must ensure that it’s not used for longer than the lifetime of the
pointed-to value.
§Example
use abi_stable::{
pointer_trait::AsMutPtr, rvec, sabi_types::MovePtr, std_types::RVec,
utils::manuallydrop_as_raw_mut,
};
use std::mem::ManuallyDrop;
let mut mdrop = ManuallyDrop::new(rvec![3, 5, 8]);
// safety: `mdrop` is never accessed again
let moveptr = unsafe { MovePtr::from_raw(manuallydrop_as_raw_mut(&mut mdrop)) };
assert_eq!(moveptr[..], [3, 5, 8]);
let vector: RVec<u8> = MovePtr::into_inner(moveptr);
assert_eq!(vector[..], [3, 5, 8]);
sourcepub const fn as_ptr(this: &Self) -> *const T
pub const fn as_ptr(this: &Self) -> *const T
Gets a raw pointer to the value being moved.
§Example
use abi_stable::{
pointer_trait::OwnedPointer, sabi_types::MovePtr, std_types::RBox,
};
let rbox = RBox::new(String::from("NOPE"));
let address_rbox = &*rbox as *const String as usize;
rbox.in_move_ptr(|move_ptr| {
assert_eq!(address_rbox, MovePtr::as_ptr(&move_ptr) as usize);
});
sourcepub fn as_mut_ptr(this: &mut Self) -> *mut T
pub fn as_mut_ptr(this: &mut Self) -> *mut T
Gets a raw pointer to the value being moved.
§Example
§Example
use abi_stable::{
pointer_trait::OwnedPointer, sabi_types::MovePtr, std_types::RBox,
};
let rbox = RBox::new(String::from("NOPE"));
let address_rbox = &*rbox as *const String as usize;
rbox.in_move_ptr(|mut move_ptr| {
assert_eq!(address_rbox, MovePtr::as_mut_ptr(&mut move_ptr) as usize);
});
sourcepub const fn into_raw(this: Self) -> *mut T
pub const fn into_raw(this: Self) -> *mut T
Converts this MovePtr into a raw pointer, which must be moved from before the pointed to value is deallocated, otherwise the value will be leaked.
§Example
use abi_stable::{
pointer_trait::OwnedPointer, sabi_types::MovePtr, std_types::RBox,
};
let rbox = RBox::new(String::from("NOPE"));
let string =
rbox.in_move_ptr(|move_ptr| unsafe { MovePtr::into_raw(move_ptr).read() });
assert_eq!(string, String::from("NOPE"));
sourcepub fn into_box(this: Self) -> Box<T>
pub fn into_box(this: Self) -> Box<T>
Moves the value into a new Box<T>
§Example
use abi_stable::{
pointer_trait::OwnedPointer, sabi_types::MovePtr, std_types::RBox,
};
let rbox = RBox::new(String::from("WHAT!!!"));
let boxed = rbox.in_move_ptr(|move_ptr| unsafe { MovePtr::into_box(move_ptr) });
assert_eq!(boxed, Box::new(String::from("WHAT!!!")));
sourcepub fn into_rbox(this: Self) -> RBox<T> ⓘ
pub fn into_rbox(this: Self) -> RBox<T> ⓘ
Moves the value into a new RBox<T>
§Example
use abi_stable::{
pointer_trait::OwnedPointer, sabi_types::MovePtr, std_types::RBox,
};
let rbox = RBox::new(String::from("WHAT!!!"));
let boxed = rbox.in_move_ptr(|move_ptr| unsafe { MovePtr::into_rbox(move_ptr) });
assert_eq!(boxed, RBox::new(String::from("WHAT!!!")));
sourcepub fn into_inner(this: Self) -> T
pub fn into_inner(this: Self) -> T
Moves the value out of the reference
§Example
use abi_stable::{
pointer_trait::OwnedPointer, sabi_types::MovePtr, std_types::RBox,
};
let rbox = RBox::new(String::from("(The Wi)zard(of)oz"));
let string = rbox.in_move_ptr(|ptr| MovePtr::into_inner(ptr));
assert_eq!(string, String::from("(The Wi)zard(of)oz"));
sourcepub const unsafe fn transmute<U>(this: Self) -> MovePtr<'a, U>where
U: 'a,
pub const unsafe fn transmute<U>(this: Self) -> MovePtr<'a, U>where
U: 'a,
Transmute this RMove<'a, T>
into a RMove<'a, U>
.
§Safety
This has the safety requirements as
std::mem::transmute
,
as well as requiring that this MovePtr
is aligned for U
.
§Example
use abi_stable::{
pointer_trait::OwnedPointer,
sabi_types::MovePtr,
std_types::{RBox, RString, RVec},
};
let rbox = RBox::new(RString::from("hello"));
let bytes = rbox.in_move_ptr(|ptr| unsafe {
MovePtr::into_inner(MovePtr::transmute::<RVec<u8>>(ptr))
});
assert_eq!(bytes.as_slice(), b"hello");
Trait Implementations§
source§impl<'a, T> GetStaticEquivalent_ for MovePtr<'a, T>where
T: __StableAbi + 'a,
impl<'a, T> GetStaticEquivalent_ for MovePtr<'a, T>where
T: __StableAbi + 'a,
source§type StaticEquivalent = _static_MovePtr<'static, <T as GetStaticEquivalent_>::StaticEquivalent>
type StaticEquivalent = _static_MovePtr<'static, <T as GetStaticEquivalent_>::StaticEquivalent>
'static
equivalent of Self
source§impl<'a, T> Ord for MovePtr<'a, T>where
T: Ord,
impl<'a, T> Ord for MovePtr<'a, T>where
T: Ord,
source§impl<'a, T> PartialOrd for MovePtr<'a, T>where
T: PartialOrd,
impl<'a, T> PartialOrd for MovePtr<'a, T>where
T: PartialOrd,
source§impl<'a, T> StableAbi for MovePtr<'a, T>where
T: __StableAbi + 'a,
impl<'a, T> StableAbi for MovePtr<'a, T>where
T: __StableAbi + 'a,
source§type IsNonZeroType = <NonNull<T> as StableAbi>::IsNonZeroType
type IsNonZeroType = <NonNull<T> as StableAbi>::IsNonZeroType
source§const LAYOUT: &'static TypeLayout = _
const LAYOUT: &'static TypeLayout = _
source§const ABI_CONSTS: AbiConsts = _
const ABI_CONSTS: AbiConsts = _
const
-equivalents of the associated types.impl<'a, T> Eq for MovePtr<'a, T>where
T: Eq,
impl<'a, T: Send> Send for MovePtr<'a, T>
impl<'a, T: Sync> Sync for MovePtr<'a, T>
Auto Trait Implementations§
impl<'a, T> Freeze for MovePtr<'a, T>
impl<'a, T> RefUnwindSafe for MovePtr<'a, T>where
T: RefUnwindSafe,
impl<'a, T> Unpin for MovePtr<'a, T>
impl<'a, T> !UnwindSafe for MovePtr<'a, T>
Blanket Implementations§
source§impl<T> AlignerFor<1> for T
impl<T> AlignerFor<1> for T
source§impl<T> AlignerFor<1024> for T
impl<T> AlignerFor<1024> for T
source§type Aligner = AlignTo1024<T>
type Aligner = AlignTo1024<T>
AlignTo*
type which aligns Self
to ALIGNMENT
.source§impl<T> AlignerFor<128> for T
impl<T> AlignerFor<128> for T
source§type Aligner = AlignTo128<T>
type Aligner = AlignTo128<T>
AlignTo*
type which aligns Self
to ALIGNMENT
.source§impl<T> AlignerFor<16> for T
impl<T> AlignerFor<16> for T
source§impl<T> AlignerFor<16384> for T
impl<T> AlignerFor<16384> for T
source§type Aligner = AlignTo16384<T>
type Aligner = AlignTo16384<T>
AlignTo*
type which aligns Self
to ALIGNMENT
.source§impl<T> AlignerFor<2> for T
impl<T> AlignerFor<2> for T
source§impl<T> AlignerFor<2048> for T
impl<T> AlignerFor<2048> for T
source§type Aligner = AlignTo2048<T>
type Aligner = AlignTo2048<T>
AlignTo*
type which aligns Self
to ALIGNMENT
.source§impl<T> AlignerFor<256> for T
impl<T> AlignerFor<256> for T
source§type Aligner = AlignTo256<T>
type Aligner = AlignTo256<T>
AlignTo*
type which aligns Self
to ALIGNMENT
.source§impl<T> AlignerFor<32> for T
impl<T> AlignerFor<32> for T
source§impl<T> AlignerFor<32768> for T
impl<T> AlignerFor<32768> for T
source§type Aligner = AlignTo32768<T>
type Aligner = AlignTo32768<T>
AlignTo*
type which aligns Self
to ALIGNMENT
.source§impl<T> AlignerFor<4> for T
impl<T> AlignerFor<4> for T
source§impl<T> AlignerFor<4096> for T
impl<T> AlignerFor<4096> for T
source§type Aligner = AlignTo4096<T>
type Aligner = AlignTo4096<T>
AlignTo*
type which aligns Self
to ALIGNMENT
.source§impl<T> AlignerFor<512> for T
impl<T> AlignerFor<512> for T
source§type Aligner = AlignTo512<T>
type Aligner = AlignTo512<T>
AlignTo*
type which aligns Self
to ALIGNMENT
.source§impl<T> AlignerFor<64> for T
impl<T> AlignerFor<64> for T
source§impl<T> AlignerFor<8> for T
impl<T> AlignerFor<8> for T
source§impl<T> AlignerFor<8192> for T
impl<T> AlignerFor<8192> for T
source§type Aligner = AlignTo8192<T>
type Aligner = AlignTo8192<T>
AlignTo*
type which aligns Self
to ALIGNMENT
.source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<S> ROExtAcc for S
impl<S> ROExtAcc for S
source§fn f_get<F>(&self, offset: FieldOffset<S, F, Aligned>) -> &F
fn f_get<F>(&self, offset: FieldOffset<S, F, Aligned>) -> &F
offset
. Read moresource§fn f_get_mut<F>(&mut self, offset: FieldOffset<S, F, Aligned>) -> &mut F
fn f_get_mut<F>(&mut self, offset: FieldOffset<S, F, Aligned>) -> &mut F
offset
. Read moresource§fn f_get_ptr<F, A>(&self, offset: FieldOffset<S, F, A>) -> *const F
fn f_get_ptr<F, A>(&self, offset: FieldOffset<S, F, A>) -> *const F
offset
. Read moresource§fn f_get_mut_ptr<F, A>(&mut self, offset: FieldOffset<S, F, A>) -> *mut F
fn f_get_mut_ptr<F, A>(&mut self, offset: FieldOffset<S, F, A>) -> *mut F
offset
. Read moresource§impl<S> ROExtOps<Aligned> for S
impl<S> ROExtOps<Aligned> for S
source§fn f_replace<F>(&mut self, offset: FieldOffset<S, F, Aligned>, value: F) -> F
fn f_replace<F>(&mut self, offset: FieldOffset<S, F, Aligned>, value: F) -> F
offset
) with value
,
returning the previous value of the field. Read moresource§fn f_get_copy<F>(&self, offset: FieldOffset<S, F, Aligned>) -> Fwhere
F: Copy,
fn f_get_copy<F>(&self, offset: FieldOffset<S, F, Aligned>) -> Fwhere
F: Copy,
source§impl<S> ROExtOps<Unaligned> for S
impl<S> ROExtOps<Unaligned> for S
source§fn f_replace<F>(&mut self, offset: FieldOffset<S, F, Unaligned>, value: F) -> F
fn f_replace<F>(&mut self, offset: FieldOffset<S, F, Unaligned>, value: F) -> F
offset
) with value
,
returning the previous value of the field. Read moresource§fn f_get_copy<F>(&self, offset: FieldOffset<S, F, Unaligned>) -> Fwhere
F: Copy,
fn f_get_copy<F>(&self, offset: FieldOffset<S, F, Unaligned>) -> Fwhere
F: Copy,
source§impl<T> SelfOps for Twhere
T: ?Sized,
impl<T> SelfOps for Twhere
T: ?Sized,
source§fn piped<F, U>(self, f: F) -> U
fn piped<F, U>(self, f: F) -> U
source§fn piped_ref<'a, F, U>(&'a self, f: F) -> Uwhere
F: FnOnce(&'a Self) -> U,
fn piped_ref<'a, F, U>(&'a self, f: F) -> Uwhere
F: FnOnce(&'a Self) -> U,
piped
except that the function takes &Self
Useful for functions that take &Self
instead of Self
. Read moresource§fn piped_mut<'a, F, U>(&'a mut self, f: F) -> Uwhere
F: FnOnce(&'a mut Self) -> U,
fn piped_mut<'a, F, U>(&'a mut self, f: F) -> Uwhere
F: FnOnce(&'a mut Self) -> U,
piped
, except that the function takes &mut Self
.
Useful for functions that take &mut Self
instead of Self
.source§fn mutated<F>(self, f: F) -> Self
fn mutated<F>(self, f: F) -> Self
source§fn observe<F>(self, f: F) -> Self
fn observe<F>(self, f: F) -> Self
source§fn as_ref_<T>(&self) -> &T
fn as_ref_<T>(&self) -> &T
AsRef
,
using the turbofish .as_ref_::<_>()
syntax. Read more