Struct abi_stable::sabi_types::rsmallbox::RSmallBox
source · #[repr(C)]pub struct RSmallBox<T, Inline> { /* private fields */ }
Expand description
A box type which stores small values inline as an optimization.
§Inline storage
The Inline
type parameter
is the storage space on the stack (as in inline with the RSmallBox
struct)
where small values get stored,instead of storing them on the heap.
It has to have an alignment greater than or equal to the value being stored, otherwise storing the value on the heap.
To ensure that the inline storage has enough alignemnt you can use one of the
AlignTo*
types from the (reexported) alignment submodule,
or from abi_stable::inline_storage::alignment
.
§Examples
§In a nonexhaustive enum
Using an RSmallBox to store a generic type in a nonexhaustive enum.
use abi_stable::{reexports::SelfOps, sabi_types::RSmallBox, std_types::RString, StableAbi};
#[repr(u8)]
#[derive(StableAbi, Debug, Clone, PartialEq)]
#[sabi(kind(WithNonExhaustive(
// Determines the maximum size of this enum in semver compatible versions.
// This is 7 usize large because:
// - The enum discriminant occupies 1 usize(because the enum is usize aligned).
// - RSmallBox<T,[usize;4]>: is 6 usize large
size = [usize;7],
// Determines the traits that are required when wrapping this enum in NonExhaustive,
// and are then available with it.
traits(Debug,Clone,PartialEq),
)))]
#[non_exhaustive]
pub enum SomeEnum<T> {
Foo,
Bar,
// This variant was added in a newer (compatible) version of the library.
Baz(RSmallBox<T, [usize; 4]>),
}
impl<T> SomeEnum<T> {
pub fn is_inline(&self) -> bool {
match self {
SomeEnum::Foo => true,
SomeEnum::Bar => true,
SomeEnum::Baz(rsbox) => RSmallBox::is_inline(rsbox),
_ => true,
}
}
pub fn is_heap_allocated(&self) -> bool {
!self.is_inline()
}
}
#[repr(C)]
#[derive(StableAbi, Debug, Clone, PartialEq)]
pub struct FullName {
pub name: RString,
pub surname: RString,
}
let rstring = "Oh boy!"
.piped(RString::from)
.piped(RSmallBox::new)
.piped(SomeEnum::Baz);
let full_name = FullName {
name: "R__e".into(),
surname: "L_____e".into(),
}
.piped(RSmallBox::new)
.piped(SomeEnum::Baz);
assert!(rstring.is_inline());
assert!(full_name.is_heap_allocated());
§Trying out different Inline
type parameters
This example demonstrates how changing the Inline
type parameter can
change whether an RString is stored inline or on the heap.
use abi_stable::{
inline_storage::alignment::AlignToUsize, sabi_types::RSmallBox, std_types::RString,
StableAbi,
};
use std::mem;
type JustRightInlineBox<T> = RSmallBox<T, AlignToUsize<[u8; mem::size_of::<usize>() * 4]>>;
let string = RString::from("What is that supposed to mean?");
let small = RSmallBox::<_, [usize; 3]>::new(string.clone());
let medium = RSmallBox::<_, [usize; 4]>::new(string.clone());
let large = RSmallBox::<_, [usize; 16]>::new(string.clone());
let not_enough_alignment = RSmallBox::<_, [u8; 64]>::new(string.clone());
let just_right = JustRightInlineBox::new(string.clone());
assert!(RSmallBox::is_heap_allocated(&small));
assert!(RSmallBox::is_inline(&medium));
assert!(RSmallBox::is_inline(&large));
assert!(RSmallBox::is_heap_allocated(¬_enough_alignment));
assert!(RSmallBox::is_inline(&just_right));
Implementations§
source§impl<T, Inline> RSmallBox<T, Inline>
impl<T, Inline> RSmallBox<T, Inline>
sourcepub fn new(value: T) -> RSmallBox<T, Inline>where
Inline: InlineStorage,
pub fn new(value: T) -> RSmallBox<T, Inline>where
Inline: InlineStorage,
Constructs this RSmallBox from a value.
§Example
use abi_stable::{sabi_types::RSmallBox, std_types::RString};
let xbox = RSmallBox::<_, [usize; 4]>::new(RString::from("one"));
sourcepub fn as_mut_ptr(this: &mut Self) -> *mut T
pub fn as_mut_ptr(this: &mut Self) -> *mut T
Gets a raw pointer into the underlying data.
§Example
use abi_stable::{sabi_types::RSmallBox, std_types::RString};
let mut play = RSmallBox::<_, [usize; 4]>::new(RString::from("station"));
let play_addr = &mut play as *mut RSmallBox<_, _> as usize;
let heap_addr = RSmallBox::as_mut_ptr(&mut play) as usize;
assert_eq!(play_addr, heap_addr);
sourcepub fn as_ptr(this: &Self) -> *const T
pub fn as_ptr(this: &Self) -> *const T
Gets a raw pointer into the underlying data.
§Example
use abi_stable::{reexports::SelfOps, sabi_types::RSmallBox, std_types::RVec};
let mut generations = vec![1, 2, 3, 4, 5, 6, 7, 8]
.piped(RVec::from)
.piped(RSmallBox::<_, [usize; 2]>::new);
let generations_addr = &generations as *const RSmallBox<_, _> as usize;
let heap_addr = RSmallBox::as_ptr(&generations) as usize;
assert_ne!(generations_addr, heap_addr);
sourcepub fn from_move_ptr(from_ptr: MovePtr<'_, T>) -> Selfwhere
Inline: InlineStorage,
pub fn from_move_ptr(from_ptr: MovePtr<'_, T>) -> Selfwhere
Inline: InlineStorage,
Constructs this RSmallBox
from a MovePtr
.
§Example
use abi_stable::{pointer_trait::OwnedPointer, sabi_types::RSmallBox, std_types::RBox};
let rbox = RBox::new(1000_u64);
let rsbox: RSmallBox<u64, [u64; 1]> =
rbox.in_move_ptr(|x| RSmallBox::<u64, [u64; 1]>::from_move_ptr(x));
assert_eq!(*rsbox, 1000_u64);
sourcepub fn move_<Inline2>(this: Self) -> RSmallBox<T, Inline2>where
Inline2: InlineStorage,
pub fn move_<Inline2>(this: Self) -> RSmallBox<T, Inline2>where
Inline2: InlineStorage,
Converts this RSmallBox
into another one with a differnet inline size.
§Example
use abi_stable::sabi_types::RSmallBox;
let old = RSmallBox::<u64, [u8; 4]>::new(599_u64);
assert!(!RSmallBox::is_inline(&old));
let new = RSmallBox::move_::<[u64; 1]>(old);
assert!(RSmallBox::is_inline(&new));
assert_eq!(*new, 599_u64);
sourcepub fn is_inline(this: &Self) -> bool
pub fn is_inline(this: &Self) -> bool
Queries whether the value is stored inline.
§Example
use abi_stable::{sabi_types::RSmallBox, std_types::RString};
let heap = RSmallBox::<u64, [u8; 4]>::new(599_u64);
assert!(!RSmallBox::is_inline(&heap));
let inline = RSmallBox::<RString, [usize; 4]>::new("hello".into());
assert!(RSmallBox::is_inline(&inline));
sourcepub fn is_heap_allocated(this: &Self) -> bool
pub fn is_heap_allocated(this: &Self) -> bool
Queries whether the value is stored on the heap.
§Example
use abi_stable::{sabi_types::RSmallBox, std_types::RHashMap};
let heap = RSmallBox::<_, [u8; 4]>::new(String::new());
assert!(RSmallBox::is_heap_allocated(&heap));
let inline = RSmallBox::<_, [usize; 3]>::new(RHashMap::<u8, ()>::new());
assert!(!RSmallBox::is_heap_allocated(&inline));
sourcepub fn into_inner(this: Self) -> T
pub fn into_inner(this: Self) -> T
Unwraps this pointer into its owned value.
§Example
use abi_stable::sabi_types::RSmallBox;
let rbox = RSmallBox::<_, [usize; 3]>::new(vec![0, 1, 2]);
assert_eq!(RSmallBox::into_inner(rbox), vec![0, 1, 2]);
Trait Implementations§
source§impl<T, O, Inline> CanTransmuteElement<O> for RSmallBox<T, Inline>
impl<T, O, Inline> CanTransmuteElement<O> for RSmallBox<T, Inline>
source§type TransmutedPtr = RSmallBox<O, Inline>
type TransmutedPtr = RSmallBox<O, Inline>
source§unsafe fn transmute_element_(self) -> Self::TransmutedPtr
unsafe fn transmute_element_(self) -> Self::TransmutedPtr
source§impl<'de, T, Inline> Deserialize<'de> for RSmallBox<T, Inline>where
Inline: InlineStorage,
T: Deserialize<'de>,
impl<'de, T, Inline> Deserialize<'de> for RSmallBox<T, Inline>where
Inline: InlineStorage,
T: Deserialize<'de>,
source§fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
source§impl<T, Inline> From<RBox<T>> for RSmallBox<T, Inline>where
Inline: InlineStorage,
impl<T, Inline> From<RBox<T>> for RSmallBox<T, Inline>where
Inline: InlineStorage,
Converts an RBox into an RSmallBox,currently this allocates.
source§impl<T, Inline> From<RSmallBox<T, Inline>> for RBox<T>where
Inline: InlineStorage,
impl<T, Inline> From<RSmallBox<T, Inline>> for RBox<T>where
Inline: InlineStorage,
Converts a RSmallBox into an RBox,currently this allocates.
source§impl<T, Inline> GetPointerKind for RSmallBox<T, Inline>
impl<T, Inline> GetPointerKind for RSmallBox<T, Inline>
source§impl<T, Inline> GetStaticEquivalent_ for RSmallBox<T, Inline>where
T: __StableAbi,
Inline: __GetStaticEquivalent_,
impl<T, Inline> GetStaticEquivalent_ for RSmallBox<T, Inline>where
T: __StableAbi,
Inline: __GetStaticEquivalent_,
source§type StaticEquivalent = _static_RSmallBox<<T as GetStaticEquivalent_>::StaticEquivalent, <Inline as GetStaticEquivalent_>::StaticEquivalent>
type StaticEquivalent = _static_RSmallBox<<T as GetStaticEquivalent_>::StaticEquivalent, <Inline as GetStaticEquivalent_>::StaticEquivalent>
'static
equivalent of Self
source§impl<T, Inline> Ord for RSmallBox<T, Inline>
impl<T, Inline> Ord for RSmallBox<T, Inline>
source§impl<T, Inline> OwnedPointer for RSmallBox<T, Inline>
impl<T, Inline> OwnedPointer for RSmallBox<T, Inline>
source§unsafe fn get_move_ptr(this: &mut ManuallyDrop<Self>) -> MovePtr<'_, T>
unsafe fn get_move_ptr(this: &mut ManuallyDrop<Self>) -> MovePtr<'_, T>
source§unsafe fn drop_allocation(this: &mut ManuallyDrop<Self>)
unsafe fn drop_allocation(this: &mut ManuallyDrop<Self>)
source§fn with_move_ptr<F, R>(this: ManuallyDrop<Self>, func: F) -> R
fn with_move_ptr<F, R>(this: ManuallyDrop<Self>, func: F) -> R
source§impl<T, Inline> PartialOrd for RSmallBox<T, Inline>where
T: PartialOrd,
Inline: PartialOrd,
impl<T, Inline> PartialOrd for RSmallBox<T, Inline>where
T: PartialOrd,
Inline: PartialOrd,
source§impl<T, Inline> StableAbi for RSmallBox<T, Inline>where
T: __StableAbi,
Inline: __GetStaticEquivalent_,
impl<T, Inline> StableAbi for RSmallBox<T, Inline>where
T: __StableAbi,
Inline: __GetStaticEquivalent_,
source§type IsNonZeroType = False
type IsNonZeroType = False
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<T, Inline> Eq for RSmallBox<T, Inline>
impl<T: Send, Inline> Send for RSmallBox<T, Inline>
impl<T: Sync, Inline> Sync for RSmallBox<T, Inline>
Auto Trait Implementations§
impl<T, Inline> Freeze for RSmallBox<T, Inline>where
Inline: Freeze,
impl<T, Inline> RefUnwindSafe for RSmallBox<T, Inline>where
T: RefUnwindSafe,
Inline: RefUnwindSafe,
impl<T, Inline> Unpin for RSmallBox<T, Inline>
impl<T, Inline> UnwindSafe for RSmallBox<T, Inline>
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<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)source§impl<'a, T> RCowCompatibleRef<'a> for Twhere
T: Clone + 'a,
impl<'a, T> RCowCompatibleRef<'a> for Twhere
T: Clone + 'a,
source§fn as_c_ref(from: &'a T) -> <T as RCowCompatibleRef<'a>>::RefC
fn as_c_ref(from: &'a T) -> <T as RCowCompatibleRef<'a>>::RefC
source§fn as_rust_ref(from: <T as RCowCompatibleRef<'a>>::RefC) -> &'a T
fn as_rust_ref(from: <T as RCowCompatibleRef<'a>>::RefC) -> &'a 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