#[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>

source

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>

Non-Send core that allows non-Send types.

source

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);
source

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>

Send core that allows only Send types.

source

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);
source

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);
source

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>

source

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);
source

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);
source

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);
source

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>());
source

pub fn current_value_type_id(&self) -> TypeId

Return TypeId of the stored value.

Examples
use dungeon_cell::{DungeonCore, layout_for};

let mut c: DungeonCore<layout_for!(u8)> = DungeonCore::new();

c.store(123u8);
assert_eq!(c.current_value_type_id(), std::any::TypeId::of::<u8>());
source

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);
source

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);
source

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));
source

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();
source

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>

Unsafe methods.

source

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.

source

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.

source

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.

source

pub unsafe fn borrow_unchecked<T: 'static>(&self) -> &T

Unchecked form of Self::borrow.

Safety

The DungeonCore must be storing a valid value of type T.

source

pub unsafe fn borrow_mut_unchecked<T: 'static>(&mut self) -> &mut T

Unchecked form of Self::borrow_mut.

Safety

The DungeonCore must be storing a valid value of type T.

source

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.

source

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>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<L: ValidLayout, S: ValidIsSend, V> Default for DungeonCore<L, S, V>where V: VTableOf<()> + VTable,

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl<L: ValidLayout, S: ValidIsSend, V: VTable> Drop for DungeonCore<L, S, V>

source§

fn drop(&mut self)

Will drop the DungeonCore and it’s stored value.

Auto Trait Implementations§

§

impl<L, S, V> RefUnwindSafe for DungeonCore<L, S, V>where V: RefUnwindSafe,

§

impl<L, S, V> Send for DungeonCore<L, S, V>where V: Send, <S as ValidIsSend>::Marker: Send,

§

impl<L, S, V> Sync for DungeonCore<L, S, V>where V: Sync,

§

impl<L, S, V> Unpin for DungeonCore<L, S, V>where V: Unpin,

§

impl<L, S, V> UnwindSafe for DungeonCore<L, S, V>where V: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

const: unstable · source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

const: unstable · source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

const: unstable · source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T, W> HasTypeWitness<W> for Twhere W: MakeTypeWitness<Arg = T>, T: ?Sized,

§

const WITNESS: W = W::MAKE

A constant of the type witness
source§

impl<T, U> Into<U> for Twhere U: From<T>,

const: unstable · source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
const: unstable · source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
const: unstable · source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.