Struct scratchpad::Allocation[][src]

pub struct Allocation<'marker, T> where
    T: ?Sized
{ /* fields omitted */ }

Scratchpad Marker allocation.

Allocations implement the Deref and DerefMut traits, allowing the data to be dereferenced explicitly using the unary * operator (e.g. *allocation) or implicitly by the compiler under various circumstances. Allocations also implement StableDeref, allowing them to be used with crates that support the trait such as owning_ref and rental.

An allocation is statically bound to the lifetime of the Marker from which it is allocated, ensuring that no dangling references can be left when the Marker is dropped.

Implementations

impl<'marker, T> Allocation<'marker, T> where
    T: Sized
[src]

pub fn unwrap(self) -> T[src]

Moves the value out of the Allocation.

Note that this is only implemented for Sized value types.

Examples

use scratchpad::Scratchpad;

let x = {
    let scratchpad = Scratchpad::<[u64; 1], [usize; 1]>::new(
        [0],
        [0],
    );
    let marker = scratchpad.mark_front().unwrap();
    let allocation = marker.allocate(3.14159).unwrap();

    allocation.unwrap()
};

// Value was moved out of the allocation, so it can now outlive the
// scratchpad in which it was initially created.
assert_eq!(x, 3.14159);

impl<'marker, T> Allocation<'marker, T> where
    T: ?Sized
[src]

pub fn into_slice_like_allocation<U: ?Sized>(self) -> Allocation<'marker, U> where
    T: IntoMutSliceLikePtr<U>,
    U: SliceLike
[src]

Converts this allocation into an allocation of a compatible SliceLike type without altering the allocation data.

Examples

use scratchpad::{Allocation, Scratchpad};

let scratchpad = Scratchpad::<[i32; 6], [usize; 1]>::static_new();
let marker = scratchpad.mark_front().unwrap();

let scalar = marker.allocate(3).unwrap();
assert_eq!(*scalar.into_slice_like_allocation(), [3]);

let slice = marker.allocate_array_with(2, |index| index as i32)
    .unwrap();
assert_eq!(*slice.into_slice_like_allocation(), [0, 1]);

// Automatic conversion of an array into a slice is ambiguous, as the
// compiler can't tell whether we want a slice with the same length as
// the array or a slice with only one element containing the entire
// array. We must explicitly specify the slice type in this example.
let array = marker.allocate([9, 8, 7]).unwrap();
let array_slice: Allocation<[i32]> = array
    .into_slice_like_allocation();
assert_eq!(*array_slice, [9, 8, 7]);

pub fn concat<U: ?Sized, V: ?Sized>(
    self,
    other: Allocation<'marker, V>
) -> Result<Allocation<'marker, U>, Error<(Allocation<'marker, T>, Allocation<'marker, V>)>> where
    T: IntoMutSliceLikePtr<U>,
    U: ConcatenateSlice,
    V: IntoMutSliceLikePtr<U>, 
[src]

Combines this allocation with an allocation immediately following it in memory, returning a single slice allocation.

Allocations must fulfill the following requirements to be able to be concatenated:

  • Each allocation must contain an instance, array, or slice of the same type. Any combination of these can be used.
  • Allocations must come from markers with the exact same lifetime. Concatenating allocations from different markers is possible, as the matching lifetimes ensure that neither marker can be invalidated before the combined allocation is dropped.
  • The first allocation must occupy the memory immediately before the second allocation. For allocations made from a MarkerBack, this means that the allocations need to be specified in the reverse order in which they were made since back markers allocate memory downwards.
  • No gaps in memory can reside between the allocations, even if that memory is no longer in use.

The first two requirements are checked at compile time, while the last two are checked at runtime.

Examples

use scratchpad::{ErrorKind, Scratchpad};

let scratchpad = Scratchpad::<[i32; 8], [usize; 2]>::static_new();

{
    let marker = scratchpad.mark_front().unwrap();
    let a = marker.allocate(1).unwrap();
    let b = marker.allocate([2, 3]).unwrap();
    let c = marker.allocate_array_with(3, |index| index as i32 + 4)
        .unwrap();

    // `a` and `c` cannot be concatenated since they are not adjacent.
    let error = a.concat(c).unwrap_err();
    assert_eq!(error.kind(), ErrorKind::NotAdjacent);
    let (a, c) = error.unwrap_args();

    // `a`, `b`, and `c` can be concatenated as long as adjacent
    // allocations are concatenated first.
    let abc = a.concat(b.concat(c).unwrap()).unwrap();
    assert_eq!(*abc, [1, 2, 3, 4, 5, 6]);
}

{
    let marker = scratchpad.mark_back().unwrap();
    let a = marker.allocate([1]).unwrap();
    let b = marker.allocate([2, 3]).unwrap();

    // When using a back marker, allocations must be concatenated in
    // the reverse order of creation.
    let error = a.concat::<[i32], _>(b).unwrap_err();
    assert_eq!(error.kind(), ErrorKind::OutOfOrder);
    let (a, b) = error.unwrap_args();

    let ba = b.concat::<[i32], _>(a).unwrap();
    assert_eq!(*ba, [2, 3, 1]);
}

{
    // Both of the markers created here exist until the end of the
    // same scope, so their allocations can be concatenated.
    let marker_a = scratchpad.mark_front().unwrap();
    let a = marker_a.allocate(1).unwrap();
    let marker_b = scratchpad.mark_front().unwrap();
    let b = marker_b.allocate(2).unwrap();

    let ab = a.concat(b).unwrap();
    assert_eq!(*ab, [1, 2]);
}

pub unsafe fn concat_unchecked<U: ?Sized, V: ?Sized>(
    self,
    other: Allocation<'marker, V>
) -> Allocation<'marker, U> where
    T: IntoMutSliceLikePtr<U>,
    U: ConcatenateSlice,
    V: IntoMutSliceLikePtr<U>, 
[src]

Combines two allocations without performing any runtime checks.

See the safe version, concat(), for requirements and additional information.

Safety

This function is unsafe because it does not check whether the allocations are adjacent in memory or whether they are specified in the correct order (with self residing immediately before other in memory). Calling this on allocations that do not fit these requirements can lead to memory corruption, undefined behavior, or crashes.

Examples

use scratchpad::{ErrorKind, Scratchpad};

let scratchpad = Scratchpad::<[i32; 3], [usize; 1]>::static_new();
let marker = scratchpad.mark_front().unwrap();

let a = marker.allocate(1).unwrap();
let b = marker.allocate([2, 3]).unwrap();

let ab = unsafe { a.concat_unchecked(b) };
assert_eq!(*ab, [1, 2, 3]);

Trait Implementations

impl<'marker, T: ?Sized> Debug for Allocation<'marker, T> where
    T: Debug
[src]

impl<'marker, T> Deref for Allocation<'marker, T> where
    T: ?Sized
[src]

type Target = T

The resulting type after dereferencing.

impl<'marker, T> DerefMut for Allocation<'marker, T> where
    T: ?Sized
[src]

impl<'marker, T> Drop for Allocation<'marker, T> where
    T: ?Sized
[src]

impl<'marker, T> StableDeref for Allocation<'marker, T>[src]

Auto Trait Implementations

impl<'marker, T: ?Sized> RefUnwindSafe for Allocation<'marker, T> where
    T: RefUnwindSafe
[src]

impl<'marker, T> !Send for Allocation<'marker, T>[src]

impl<'marker, T> !Sync for Allocation<'marker, T>[src]

impl<'marker, T: ?Sized> Unpin for Allocation<'marker, T>[src]

impl<'marker, T: ?Sized> UnwindSafe for Allocation<'marker, T> where
    T: RefUnwindSafe
[src]

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.