Struct dungeon_cell::DungeonCore
source · #[repr(transparent)]pub struct DungeonCore<L, S = IsSend<false>, V = &'static CoreVTable>where
L: ValidLayout,
S: ValidIsSend,
V: VTable,{ /* private fields */ }
Expand description
Core of a dungeon type.
A DungeonCore
can store any static type (lives for 'static
) that fits in
it’s layout L
. This type does not perform
any dynamic memory allocation. It can be thought of as a single value arena.
The space overhead of DungeonCore
is kept as small as possible. In most cases,
the space overhead of DungeonCore
is the size of a single usize
. The
space overhead is directly tied to the size of the V
type.
A DungeonCore
will implement std::marker::Send
when S
is IsSend<true>
.
When this is the case, all values stored in the core must also be Send
.
Examples
use dungeon_cell::{DungeonCore, layout_for};
let mut c: DungeonCore<layout_for!(i32, f64)> = DungeonCore::new();
// we can store a i32 and get it back
c.store(1234);
assert_eq!(c.take::<i32>(), Some(1234));
// we can store a f64 and get it back
c.store(1.234);
assert_eq!(c.take::<f64>(), Some(1.234));
// we can't take a type the core isn't storing
c.store(1234);
assert_eq!(c.take::<f64>(), None);
// we can borrow both unique and shared
c.store(1234);
*c.borrow_mut::<i32>().unwrap() += 10;
assert_eq!(c.borrow::<i32>(), Some(&1244));
Implementations§
source§impl<L: ValidLayout, S: ValidIsSend, V: VTable> DungeonCore<L, S, V>
impl<L: ValidLayout, S: ValidIsSend, V: VTable> DungeonCore<L, S, V>
sourcepub const fn new() -> Selfwhere
V: ConstVTableOf<()>,
pub const fn new() -> Selfwhere V: ConstVTableOf<()>,
Create an empty DungeonCore
containing a ()
.
Examples
use dungeon_cell::{DungeonCore, layout_for};
let c: DungeonCore<layout_for!()> = DungeonCore::new();
source§impl<L: ValidLayout, V: VTable> DungeonCore<L, IsSend<false>, V>
impl<L: ValidLayout, V: VTable> DungeonCore<L, IsSend<false>, V>
sourcepub const fn from<T: 'static>(value: T) -> Selfwhere
L: CanStore<T>,
V: ConstVTableOf<T>,
pub const fn from<T: 'static>(value: T) -> Selfwhere L: CanStore<T>, V: ConstVTableOf<T>,
Create a DungeonCore
from a value.
Examples
use dungeon_cell::{DungeonCore, layout_for, IsSend};
let c = DungeonCore::<layout_for!(i32), IsSend<false>>::from(123_i32);
sourcepub fn store<T: 'static>(&mut self, value: T)where
L: CanStore<T>,
V: VTableOf<T>,
pub fn store<T: 'static>(&mut self, value: T)where L: CanStore<T>, V: VTableOf<T>,
Store a value of type T
.
The currently stored value will be dropped.
Panics
This function will panic when runtime checks are enabled, as described by
CanStore::assert_can_store()
’s documentation, and the type T
cannot
be stored in the core.
Examples
use dungeon_cell::{DungeonCore, layout_for, IsSend};
let mut c: DungeonCore<layout_for!(u8), IsSend<false>> = DungeonCore::new();
c.store(4u8);
assert_eq!(c.take::<u8>(), Some(4));
Storing non-Send
types
use std::rc::Rc;
use dungeon_cell::{DungeonCore, layout_for, IsSend};
let mut c: DungeonCore<layout_for!(Rc<i32>), IsSend<false>> = DungeonCore::new();
c.store(Rc::new(4));
assert_eq!(*c.take::<Rc<i32>>().unwrap(), 4);
source§impl<L: ValidLayout, V: VTable> DungeonCore<L, IsSend<true>, V>
impl<L: ValidLayout, V: VTable> DungeonCore<L, IsSend<true>, V>
sourcepub const fn from<T: Send + 'static>(value: T) -> Selfwhere
L: CanStore<T>,
V: ConstVTableOf<T>,
pub const fn from<T: Send + 'static>(value: T) -> Selfwhere L: CanStore<T>, V: ConstVTableOf<T>,
Create a DungeonCore
from a value.
Examples
use dungeon_cell::{DungeonCore, layout_for, IsSend};
let c = DungeonCore::<layout_for!(i32), IsSend<true>>::from(123_i32);
sourcepub fn store<T: Send + 'static>(&mut self, value: T)where
L: CanStore<T>,
V: VTableOf<T>,
pub fn store<T: Send + 'static>(&mut self, value: T)where L: CanStore<T>, V: VTableOf<T>,
Store a value of type T
.
Same as DungeonCore<T, IsSend<false>, V>::store()
except only
Send
types are allowed.
Examples
use dungeon_cell::{DungeonCore, layout_for, IsSend};
let mut c: DungeonCore<layout_for!(u8), IsSend<true>> = DungeonCore::new();
c.store(4u8);
assert_eq!(c.take::<u8>(), Some(4));
Using Send
use dungeon_cell::{DungeonCore, layout_for, IsSend};
fn test<T: Send>(value: T) -> T {
value
}
let mut c: DungeonCore<layout_for!(u8), IsSend<true>> = DungeonCore::new();
c.store(4u8);
let c = test(c);
assert_eq!(c.borrow::<u8>(), Some(&4));
Storing non-Send
types
This fails because the DungeonCore
is marked as Send
.
use std::rc::Rc;
use dungeon_cell::{DungeonCore, layout_for, IsSend};
let mut c: DungeonCore<layout_for!(Rc<i32>), IsSend<true>> = DungeonCore::new()
c.store(Rc::new(4));
assert_eq!(*c.take::<Rc<i32>>().unwrap(), 4);
sourcepub fn into_not_send(self) -> DungeonCore<L, IsSend<false>, V>
pub fn into_not_send(self) -> DungeonCore<L, IsSend<false>, V>
Convert a DungeonCore
that implements Send
to one that does not.
This is a one way operation. You can’t construct a Send
implementing
DungeonCore
from the returned value because we can’t be sure the
stored value implements Send
.
Examples
use dungeon_cell::{DungeonCore, layout_for, IsSend};
let mut c: DungeonCore<layout_for!(u8), IsSend<true>> = DungeonCore::new();
c.store(4u8);
// now c can't be used where a `Send` type is needed.
let c = c.into_not_send();
assert_eq!(c.borrow::<u8>(), Some(&4));
source§impl<L: ValidLayout, S: ValidIsSend, V: VTable> DungeonCore<L, S, V>
impl<L: ValidLayout, S: ValidIsSend, V: VTable> DungeonCore<L, S, V>
sourcepub fn take<T: 'static>(&mut self) -> Option<T>where
V: VTableOf<()>,
pub fn take<T: 'static>(&mut self) -> Option<T>where V: VTableOf<()>,
Gain ownership of the value inside the DungeonCore
.
This will leave the DungeonCore
storing a ()
if the currently stored
value is of type T
. If the DungeonCore
is storing a value of another
type, then a None
is returned and the stored value is unaffected.
Examples
use dungeon_cell::{DungeonCore, layout_for};
let mut c: DungeonCore<layout_for!(u8)> = DungeonCore::new();
c.store(4u8);
assert_eq!(c.take::<u8>(), Some(4));
assert_eq!(c.take::<u8>(), None);
sourcepub fn borrow<T: 'static>(&self) -> Option<&T>
pub fn borrow<T: 'static>(&self) -> Option<&T>
Borrow the stored value.
If the DungeonCore
is storing a value of another type, then a None
is returned.
Examples
use dungeon_cell::{DungeonCore, layout_for};
let mut c: DungeonCore<layout_for!(u8)> = DungeonCore::new();
c.store(4u8);
assert_eq!(c.borrow::<u8>(), Some(&4));
assert_eq!(c.borrow::<i8>(), None);
sourcepub fn borrow_mut<T: 'static>(&mut self) -> Option<&mut T>
pub fn borrow_mut<T: 'static>(&mut self) -> Option<&mut T>
Mutably borrow the stored value.
If the DungeonCore
is storing a value of another type, then a None
is returned.
Examples
use dungeon_cell::{DungeonCore, layout_for};
let mut c: DungeonCore<layout_for!(u8)> = DungeonCore::new();
c.store(4u8);
*c.borrow_mut::<u8>().unwrap() += 2;
assert_eq!(c.take::<u8>(), Some(6));
assert_eq!(c.borrow_mut::<u8>(), None);
sourcepub fn is_value_type<T: 'static>(&self) -> bool
pub fn is_value_type<T: 'static>(&self) -> bool
Check if the value being stored is of type T
.
Examples
use dungeon_cell::{DungeonCore, layout_for};
let mut c: DungeonCore<layout_for!(u8)> = DungeonCore::new();
assert!(!c.is_value_type::<u8>());
c.store(4u8);
assert!(c.is_value_type::<u8>());
assert!(!c.is_value_type::<i8>());
assert!(!c.is_value_type::<u64>());
sourcepub fn current_value_type_id(&self) -> TypeId
pub fn current_value_type_id(&self) -> TypeId
sourcepub fn current_value_size(&self) -> usize
pub fn current_value_size(&self) -> usize
Return the size of the stored value.
Examples
use dungeon_cell::{DungeonCore, layout_for};
let mut c: DungeonCore<layout_for!(u8, u16)> = DungeonCore::new();
c.store(123u8);
assert_eq!(c.current_value_size(), 1);
sourcepub fn current_value_alignment(&self) -> usize
pub fn current_value_alignment(&self) -> usize
Return the alignment of the stored value.
Examples
use dungeon_cell::{DungeonCore, layout_for};
let mut c: DungeonCore<layout_for!(u8, u16)> = DungeonCore::new();
c.store(123u8);
assert_eq!(c.current_value_alignment(), 1);
sourcepub fn try_swap<L2: ValidLayout>(
&mut self,
other: &mut DungeonCore<L2, S, V>
) -> bool
pub fn try_swap<L2: ValidLayout>( &mut self, other: &mut DungeonCore<L2, S, V> ) -> bool
Try to swap the values of this DungeonCore
with another one.
The values can only be swapped if they can be stored in
the opposite core. A true
will be returned if the swap happened.
Examples
use dungeon_cell::{DungeonCore, layout_for};
let mut a = DungeonCore::<layout_for!(i32)>::from(123u8);
let mut b = DungeonCore::<layout_for!(i16)>::from(456u16);
assert!(a.try_swap(&mut b));
assert_eq!(a.take::<u16>(), Some(456));
assert_eq!(b.take::<u8>(), Some(123));
use dungeon_cell::{DungeonCore, layout_for};
let mut a = DungeonCore::<layout_for!(u8)>::from(123u8);
let mut b = DungeonCore::<layout_for!(u16)>::from(456u16);
assert!(!a.try_swap(&mut b));
assert_eq!(a.take::<u8>(), Some(123));
assert_eq!(b.take::<u16>(), Some(456));
sourcepub fn into_larger<L2>(self) -> DungeonCore<L2, S, V>where
L2: CanStore<OpaqueType<L>> + ValidLayout,
pub fn into_larger<L2>(self) -> DungeonCore<L2, S, V>where L2: CanStore<OpaqueType<L>> + ValidLayout,
Convert the DungeonCore
into a larger size or alignment DungeonCore
.
Panics
This function will panic when runtime checks are enabled, as described by
CanStore::assert_can_store()
’s documentation, and the current core cannot
be stored in the new core.
Examples
use dungeon_cell::{DungeonCore, layout_for, IsSend};
let c: DungeonCore<layout_for!(u8)> = DungeonCore::<_, IsSend<false>>::from(123u8);
let mut c: DungeonCore<layout_for!(u16)> = c.into_larger();
assert_eq!(c.take::<u8>(), Some(123));
use dungeon_cell::{DungeonCore, layout_for, IsSend};
let c: DungeonCore<layout_for!(u16)> = DungeonCore::<_, IsSend<false>>::from(123u16);
let c: DungeonCore<layout_for!(u8)> = c.into_larger();
sourcepub fn try_into_smaller<L2: ValidLayout>(
self
) -> Result<DungeonCore<L2, S, V>, Self>
pub fn try_into_smaller<L2: ValidLayout>( self ) -> Result<DungeonCore<L2, S, V>, Self>
Try to convert the DungeonCore
into a smaller size or alignment DungeonCore
This is only possible if the value stored can be stored in the smaller DungeonCore
.
A Err()
with the current DungeonCore
will be returned if the value cannot be
stored in the smaller core.
This method will return Ok()
for all cases where Self::into_larger()
works.
Examples
use dungeon_cell::{DungeonCore, layout_for, IsSend};
let c: DungeonCore<layout_for!(u16)> = DungeonCore::<_, IsSend<false>>::from(123u8);
let mut c: DungeonCore<layout_for!(u8)> = c.try_into_smaller().unwrap();
assert_eq!(c.take::<u8>(), Some(123));
use dungeon_cell::{DungeonCore, layout_for, IsSend};
let c: DungeonCore<layout_for!(u16)> = DungeonCore::<_, IsSend<false>>::from(123u16);
assert!(c.try_into_smaller::<layout_for!(u8)>().is_err());
source§impl<L: ValidLayout, S: ValidIsSend, V: VTable> DungeonCore<L, S, V>
impl<L: ValidLayout, S: ValidIsSend, V: VTable> DungeonCore<L, S, V>
Unsafe methods.
sourcepub const unsafe fn from_unchecked<T: 'static>(value: T, vtable: V) -> Selfwhere
L: CanStore<T>,
pub const unsafe fn from_unchecked<T: 'static>(value: T, vtable: V) -> Selfwhere L: CanStore<T>,
Create core from a value and a vtable.
Safety
The vtable
must be for the type T
. Additionally, if S
is
IsSend<true>
then T
must implement Send
.
sourcepub unsafe fn store_unchecked<T: 'static>(&mut self, value: T, vtable: V)where
L: CanStore<T>,
pub unsafe fn store_unchecked<T: 'static>(&mut self, value: T, vtable: V)where L: CanStore<T>,
Unchecked form of Self::store.
If the DungeonCore
is not empty, then the stored value will
be forgotten.
Safety
The vtable
must be for the type T
. Additionally, if S
is
IsSend<true>
then T
must implement Send
.
sourcepub unsafe fn take_unchecked<T: 'static>(&mut self) -> (T, V)where
V: VTableOf<()>,
pub unsafe fn take_unchecked<T: 'static>(&mut self) -> (T, V)where V: VTableOf<()>,
Unchecked form of Self::take.
The vtable instance for the value is also returned.
Safety
The DungeonCore
must be storing a valid value of type T
.
sourcepub unsafe fn borrow_unchecked<T: 'static>(&self) -> &T
pub unsafe fn borrow_unchecked<T: 'static>(&self) -> &T
sourcepub unsafe fn borrow_mut_unchecked<T: 'static>(&mut self) -> &mut T
pub unsafe fn borrow_mut_unchecked<T: 'static>(&mut self) -> &mut T
sourcepub unsafe fn raw_internals(&self) -> (&V, &[MaybeUninit<u8>])
pub unsafe fn raw_internals(&self) -> (&V, &[MaybeUninit<u8>])
Get the internal vtable and buffer of the DungeonCore
.
Invariants
The buffer contains a valid value of the type the vtable is for.
Additionally, the buffer has the layout described by generic L
.
Safety
After the borrow of self
ends, the buffer must still contain a valid
value of the type the vtable is for. Both the vtable and value in the buffer
can change. The vtable and buffer must be valid in the event of a panic.
sourcepub unsafe fn raw_internals_mut(&mut self) -> (&mut V, &mut [MaybeUninit<u8>])
pub unsafe fn raw_internals_mut(&mut self) -> (&mut V, &mut [MaybeUninit<u8>])
Get the internal vtable and buffer of the DungeonCore
mutably.
Invariants
The buffer contains a valid value of the type the vtable is for.
Additionally, the buffer has the layout described by generic L
.
Safety
After the borrow of self
ends, the buffer must still contain a valid
value of the type the vtable is for. Both the vtable and value in the buffer
can change. The vtable and buffer must be valid in the event of a panic.
Trait Implementations§
source§impl<L: ValidLayout, S: ValidIsSend, V: VTable> Debug for DungeonCore<L, S, V>
impl<L: ValidLayout, S: ValidIsSend, V: VTable> Debug for DungeonCore<L, S, V>
source§impl<L: ValidLayout, S: ValidIsSend, V> Default for DungeonCore<L, S, V>where
V: VTableOf<()> + VTable,
impl<L: ValidLayout, S: ValidIsSend, V> Default for DungeonCore<L, S, V>where V: VTableOf<()> + VTable,
source§impl<L: ValidLayout, S: ValidIsSend, V: VTable> Drop for DungeonCore<L, S, V>
impl<L: ValidLayout, S: ValidIsSend, V: VTable> Drop for DungeonCore<L, S, V>
source§fn drop(&mut self)
fn drop(&mut self)
Will drop the DungeonCore
and it’s stored value.