renamed Value<T> to SmallBox<T>
This commit is contained in:
parent
2ef2744eca
commit
5881f8e26a
|
@ -170,11 +170,13 @@ mod util {
|
|||
mod job {
|
||||
use std::{
|
||||
any::Any,
|
||||
borrow::{Borrow, BorrowMut},
|
||||
cell::UnsafeCell,
|
||||
fmt::Debug,
|
||||
fmt::{Debug, Display},
|
||||
hint::cold_path,
|
||||
marker::PhantomPinned,
|
||||
mem::{self, ManuallyDrop, MaybeUninit},
|
||||
ops::{Deref, DerefMut},
|
||||
pin::Pin,
|
||||
ptr::{self, NonNull},
|
||||
sync::atomic::Ordering,
|
||||
|
@ -185,23 +187,114 @@ mod job {
|
|||
|
||||
use super::util::TaggedAtomicPtr;
|
||||
|
||||
pub struct Value<T>(pub MaybeUninit<Box<MaybeUninit<T>>>);
|
||||
#[derive(Debug)]
|
||||
pub struct SmallBox<T>(pub MaybeUninit<Box<T>>);
|
||||
|
||||
impl<T> Value<T> {
|
||||
impl<T: Display> Display for SmallBox<T> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
(**self).fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Ord> Ord for SmallBox<T> {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
self.as_ref().cmp(other.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PartialOrd> PartialOrd for SmallBox<T> {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
self.as_ref().partial_cmp(other.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Eq> Eq for SmallBox<T> {}
|
||||
|
||||
impl<T: PartialEq> PartialEq for SmallBox<T> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.as_ref().eq(other.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Default> Default for SmallBox<T> {
|
||||
fn default() -> Self {
|
||||
Self::new(Default::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone> Clone for SmallBox<T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self::new(self.as_ref().clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Deref for SmallBox<T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> DerefMut for SmallBox<T> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
self.as_mut()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> AsRef<T> for SmallBox<T> {
|
||||
fn as_ref(&self) -> &T {
|
||||
Self::as_ref(self)
|
||||
}
|
||||
}
|
||||
impl<T> AsMut<T> for SmallBox<T> {
|
||||
fn as_mut(&mut self) -> &mut T {
|
||||
Self::as_mut(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Borrow<T> for SmallBox<T> {
|
||||
fn borrow(&self) -> &T {
|
||||
&**self
|
||||
}
|
||||
}
|
||||
impl<T> BorrowMut<T> for SmallBox<T> {
|
||||
fn borrow_mut(&mut self) -> &mut T {
|
||||
&mut **self
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> SmallBox<T> {
|
||||
/// must only be called once. takes a reference so this can be called in
|
||||
/// drop()
|
||||
unsafe fn get_unchecked(&self, inline: bool) -> T {
|
||||
if inline {
|
||||
unsafe { mem::transmute_copy::<MaybeUninit<Box<MaybeUninit<T>>>, T>(&self.0) }
|
||||
unsafe { mem::transmute_copy::<MaybeUninit<Box<T>>, T>(&self.0) }
|
||||
} else {
|
||||
unsafe {
|
||||
let inner = *self.0.assume_init_read();
|
||||
inner.assume_init()
|
||||
unsafe { *self.0.assume_init_read() }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_ref(&self) -> &T {
|
||||
unsafe {
|
||||
if Self::is_inline() {
|
||||
mem::transmute::<&MaybeUninit<Box<T>>, &T>(&self.0)
|
||||
} else {
|
||||
self.0.assume_init_ref()
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn as_mut(&mut self) -> &mut T {
|
||||
unsafe {
|
||||
if Self::is_inline() {
|
||||
mem::transmute::<&mut MaybeUninit<Box<T>>, &mut T>(&mut self.0)
|
||||
} else {
|
||||
self.0.assume_init_mut()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(self) -> T {
|
||||
pub fn into_inner(self) -> T {
|
||||
let this = ManuallyDrop::new(self);
|
||||
let inline = Self::is_inline();
|
||||
|
||||
|
@ -228,12 +321,12 @@ mod job {
|
|||
this.assume_init()
|
||||
}
|
||||
} else {
|
||||
Self(MaybeUninit::new(Box::new(MaybeUninit::new(value))))
|
||||
Self(MaybeUninit::new(Box::new(value)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Drop for Value<T> {
|
||||
impl<T> Drop for SmallBox<T> {
|
||||
fn drop(&mut self) {
|
||||
// drop contained value.
|
||||
drop(unsafe { self.get_unchecked(Self::is_inline()) });
|
||||
|
@ -374,7 +467,7 @@ mod job {
|
|||
|
||||
union ValueOrThis<T> {
|
||||
uninit: (),
|
||||
value: ManuallyDrop<Value<T>>,
|
||||
value: ManuallyDrop<SmallBox<T>>,
|
||||
this: NonNull<()>,
|
||||
}
|
||||
|
||||
|
@ -568,7 +661,7 @@ mod job {
|
|||
ManuallyDrop::take(&mut (&mut *self.val_or_this.get()).value)
|
||||
};
|
||||
|
||||
Ok(val.get())
|
||||
Ok(val.into_inner())
|
||||
};
|
||||
|
||||
return result;
|
||||
|
@ -647,7 +740,7 @@ mod job {
|
|||
|
||||
match result {
|
||||
Ok(val) => unsafe {
|
||||
(&mut *self.val_or_this.get()).value = ManuallyDrop::new(Value::new(val));
|
||||
(&mut *self.val_or_this.get()).value = ManuallyDrop::new(SmallBox::new(val));
|
||||
(&mut *self.err_or_link.get()).error = ManuallyDrop::new(None);
|
||||
},
|
||||
Err(err) => unsafe {
|
||||
|
|
|
@ -201,9 +201,9 @@ fn tagged_ptr_exchange_failure() {
|
|||
|
||||
#[test]
|
||||
fn value_inline() {
|
||||
let val = Value::new(3usize);
|
||||
let val = SmallBox::new(3usize);
|
||||
|
||||
let inner = val.get();
|
||||
let inner = val.into_inner();
|
||||
assert_eq!(inner, 3usize);
|
||||
}
|
||||
|
||||
|
@ -213,15 +213,15 @@ fn value_inline_struct() {
|
|||
struct Small {
|
||||
c: f32,
|
||||
}
|
||||
let val = Value::new(Small { c: 3.2 });
|
||||
let val = SmallBox::new(Small { c: 3.2 });
|
||||
|
||||
let inner = val.get();
|
||||
let inner = val.into_inner();
|
||||
assert_eq!(inner.c, 3.2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn value_inline_ptr_sized() {
|
||||
assert!(Value::<usize>::is_inline());
|
||||
assert!(SmallBox::<usize>::is_inline());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -232,13 +232,13 @@ fn value_boxed() {
|
|||
b: f32,
|
||||
c: u32,
|
||||
}
|
||||
let val = Value::new(Big {
|
||||
let val = SmallBox::new(Big {
|
||||
a: 42,
|
||||
b: 2.25,
|
||||
c: 7,
|
||||
});
|
||||
|
||||
let inner = val.get();
|
||||
let inner = val.into_inner();
|
||||
assert_eq!(
|
||||
inner,
|
||||
Big {
|
||||
|
@ -261,21 +261,21 @@ fn value_inline_drop() {
|
|||
*self.inner += 1;
|
||||
}
|
||||
}
|
||||
assert!(Value::<Small<'_>>::is_inline());
|
||||
assert!(SmallBox::<Small<'_>>::is_inline());
|
||||
let mut dropped = 0;
|
||||
{
|
||||
let inner = {
|
||||
let val = Value::new(Small {
|
||||
let val = SmallBox::new(Small {
|
||||
inner: &mut dropped,
|
||||
});
|
||||
|
||||
val.get()
|
||||
val.into_inner()
|
||||
};
|
||||
assert_eq!(*inner.inner, 0);
|
||||
}
|
||||
assert_eq!(dropped, 1);
|
||||
{
|
||||
let _val = Value::new(Small {
|
||||
let _val = SmallBox::new(Small {
|
||||
inner: &mut dropped,
|
||||
});
|
||||
}
|
||||
|
@ -297,18 +297,18 @@ fn value_boxed_drop() {
|
|||
let mut dropped = 0;
|
||||
{
|
||||
let inner = {
|
||||
let val = Value::new(Big {
|
||||
let val = SmallBox::new(Big {
|
||||
inner: &mut dropped,
|
||||
pad: [0; 3],
|
||||
});
|
||||
|
||||
val.get()
|
||||
val.into_inner()
|
||||
};
|
||||
assert_eq!(*inner.inner, 0);
|
||||
}
|
||||
assert_eq!(dropped, 1);
|
||||
{
|
||||
let _val = Value::new(Big {
|
||||
let _val = SmallBox::new(Big {
|
||||
inner: &mut dropped,
|
||||
pad: [0; 3],
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue