[][src]Struct const_buffer::ConstBuffer

pub struct ConstBuffer<T, const N: usize>(_);

A fixed-capacity buffer allocated on the stack using const generics.

Methods

impl<T, const N: usize> ConstBuffer<T, N>[src]

pub const fn from_array(array: [T; N]) -> Self[src]

Creates a new ConstBuffer from an array with the same size.

pub const fn new() -> Self[src]

Creates a new ConstBuffer with all elements in an uninitialized state.

pub fn zeroed() -> Self[src]

Creates a new ConstBuffer with all elements in an uninitialized state, with the memory being filled with 0 bytes. It depends on T whether that already makes for proper initialization. For example, ConstBuffer<usize, N>::zeroed() is initialized, but ConstBuffer<&'static i32, N>::zeroed() is not because references must not be null.

Examples

Correct usage of this function:

let buffer = ConstBuffer::<u32, 10>::zeroed();
for i in 0..10 {
    unsafe { assert_eq!(buffer.read(i), 0) };
}

Incorrect usage of this function:

let buffer = ConstBuffer::<&'static u32, 10>::zeroed();
let x = unsafe { buffer.read(0) };

pub const fn as_ptr(&self) -> *const T[src]

Returns a pointer to the buffer.

It is up to the caller to ensure that the buffer outlives the pointer returned from this method, or else it will end up pointing to garbage.

It is also up to the caller to ensure that the memory this pointer points to is never written to using this pointer or any pointer derived from it.

Examples

let mut buffer = ConstBuffer::<usize, 6>::zeroed();

unsafe {
    buffer.write(1, 10);
    buffer.write(3, 30);
    buffer.write(5, 50);

    let mut p = buffer.as_ptr();
    for i in 0..6 {
        if i % 2 == 1 {
            assert_eq!(std::ptr::read(p), 10 * i);
        }
        p = p.add(1);
    }
}

pub const fn as_mut_ptr(&mut self) -> *mut T[src]

Returns a mutable pointer to the buffer.

It is up to the caller to ensure that the buffer outlives the pointer returned from this method, or else it will end up pointing to garbage.

Examples

let mut buffer = ConstBuffer::<usize, 6>::zeroed();

unsafe {
    let mut p = buffer.as_mut_ptr();
    for i in 0..6 {
        if i % 2 == 1 {
            std::ptr::write(p, 10 * i);
        }
        p = p.add(1);
    }

    assert_eq!(buffer.read(1), 10);
    assert_eq!(buffer.read(3), 30);
    assert_eq!(buffer.read(5), 50);
}

pub unsafe fn read(&self, index: usize) -> T[src]

Reads the element at index.

Safety

It is up to the caller to ensure that index is not out of bounds, and that the element at index is in an initialized state.

Examples

let mut buffer = ConstBuffer::<u32, 10>::new();

unsafe {
    buffer.write(3, 123);
    assert_eq!(buffer.read(3), 123);
}

pub unsafe fn write(&mut self, index: usize, value: T) -> &mut T[src]

Sets the element at index.

This overwrites any previous element at that index without dropping it, and returns a mutable reference to the (now safely initialized) element at index.

Safety

It is up to the caller to ensure that index is not out of bounds. The old contents at index aren't dropped, so the element at index does not need to be in an initialized state.

Examples

let mut buffer = ConstBuffer::<u32, 10>::new();

unsafe {
    let x = buffer.write(3, 123);
    *x *= 3;
    assert_eq!(buffer.read(3), 369);
}

pub unsafe fn get<'a, I>(&'a self, index: I) -> &I::Output where
    I: BufferIndex<'a, T>, 
[src]

Returns a reference to an element or subslice depending on the type of index.

  • Given a position, this returns a reference to the element at that position.
  • Given a range, this returns the subslice corresponding to that range.

Safety

It is up to the caller to ensure that the position or range is not out of bounds, and that the corresponding elements are in an initialized state.

Examples

Correct usage of this method:

let mut buffer = ConstBuffer::<u32, 10>::new();

unsafe {
    buffer.write(3, 30);
    buffer.write(4, 40);
    buffer.write(5, 50);

    assert_eq!(buffer.get(3), &30);
    assert_eq!(buffer.get(4..6), &[40, 50]);
}

Incorrect usage of this method:

let buffer = ConstBuffer::<u32, 10>::new();
let x = unsafe { buffer.get(0) };
// We have created a reference to an uninitialized value! This is
// undefined behavior.

pub unsafe fn get_mut<'a, I>(&'a mut self, index: I) -> &mut I::Output where
    I: BufferIndex<'a, T>, 
[src]

Returns a mutable reference to an element or subslice depending on the type of index.

Safety

It is up to the caller to ensure that the position or range is not out of bounds, and that the corresponding elements are in an initialized state.

Examples

Correct usage of this method:

let mut buffer = ConstBuffer::<u32, 10>::new();

unsafe {
    buffer.write(3, 30);
    buffer.write(4, 40);
    buffer.write(5, 50);

    *buffer.get_mut(3) += 5;
    buffer.get_mut(4..6).reverse();

    assert_eq!(buffer.read(3), 35);
    assert_eq!(buffer.read(4), 50);
    assert_eq!(buffer.read(5), 40);
}

Incorrect usage of this method:

let mut buffer = ConstBuffer::<u32, 10>::new();

unsafe {
    // We create a reference to uninitialized memory which is
    // undefined behavior, despite not reading from it.
    *buffer.get_mut(3) = 5;
    assert_eq!(buffer.read(3), 5);
}

pub unsafe fn swap(&mut self, i: usize, j: usize)[src]

Swaps the elements at indices i and j. i and j may be equal.

Safety

It is up to the caller to ensure that i and j are not out of bounds.

Examples

let mut buffer = ConstBuffer::<u32, 10>::new();

unsafe {
    buffer.write(3, 10);
    buffer.write(5, 20);

    buffer.swap(3, 3);
    buffer.swap(3, 5);

    assert_eq!(buffer.read(3), 20);
    assert_eq!(buffer.read(5), 10);
}

pub unsafe fn swap_nonoverlapping(&mut self, i: usize, j: usize)[src]

Swaps the elements at indices i and j. i and j must not be equal to each other.

Safety

It is up to the caller to ensure that i and j are not out of bounds, and that i and j are not equal to each other.

Examples

let mut buffer = ConstBuffer::<u32, 10>::new();

unsafe {
    buffer.write(3, 10);
    buffer.write(5, 20);

    buffer.swap(3, 5);

    assert_eq!(buffer.read(3), 20);
    assert_eq!(buffer.read(5), 10);
}

pub fn resize<const M: usize>(&self) -> ConstBuffer<T, M>[src]

Creates a new buffer with a potentially different size.

If the new buffer is larger than the original buffer, all the contents of the original buffer are copied over to the new buffer, and the rest will be uninitialized.

If the new buffer is smaller than the original buffer, the new buffer will be filled entirely with contents of the original buffer, ignoring any excess elements at the end.

Note that this simply copies the bytes of the original buffer to the new buffer, and it does not call clone on any of the elements in the buffer. Therefore, if you end up reading the same element from both buffers, it is your responsibility to ensure that that data may indeed be duplicated.

If you want clone to be called on the elements in the buffer, consider using clone_from_slice instead.

Examples

let mut buffer = ConstBuffer::<u32, 10>::new();

unsafe {
    buffer.write(3, 30);
    buffer.write(7, 70);
}

let small: ConstBuffer<u32, 5> = buffer.resize();
let large: ConstBuffer<u32, 15> = buffer.resize();

unsafe {
    assert_eq!(small.read(3), 30);

    // This read would be out-of-bounds.
    // assert_eq!(small.read(7), 70);

    assert_eq!(large.read(3), 30);
    assert_eq!(large.read(7), 70);
}

pub unsafe fn copy_within<R>(&mut self, src: R, dest: usize) where
    R: RangeBounds<usize>, 
[src]

Copies elements from one part of the buffer to another part of itself.

src is the range within self to copy from. This range is allowed to contain uninitialized elements. dest is the starting index of the range within self to copy to, which will have the same length as src. The two ranges may overlap.

Note that unlike slice::copy_within, this method does not require that T implements Copy.

Safety

It is up to the caller to ensure that the two ranges are in-bounds, and that the end of src is before the start.

Examples

Correct usage of this method:

let mut buffer = ConstBuffer::<u32, 10>::new();

unsafe {
    buffer.write(2, 10);
    buffer.write(5, 20);
    buffer.write(7, 30);

    // This overwrites the elements in 1..7 with the elements in
    // 4..10, so 20 ends up at index 2 and 30 at index 4.
    buffer.copy_within(4.., 1);

    assert_eq!(buffer.read(2), 20);
    assert_eq!(buffer.read(4), 30);

    // The element at index 7 is still there:
    assert_eq!(buffer.read(7), 30);
}

Incorrect usage of this method:

let mut buffer = ConstBuffer::<u32, 10>::new();

// This will try to copy the elements from 0..5 to 8..13,
// which is out-of-bounds.
unsafe { buffer.copy_within(..5, 8); }

pub unsafe fn copy_within_nonoverlapping<R>(&mut self, src: R, dest: usize) where
    R: RangeBounds<usize>, 
[src]

Copies elements from one part of the buffer to another part of itself. The source and destination must not overlap.

src is the range within self to copy from. This range is allowed to contain uninitialized elements. dest is the starting index of the range within self to copy to, which will have the same length as src. The two ranges must not overlap.

Note that unlike slice::copy_within, this method does not require that T implements Copy.

For ranges that might overlap, use copy_within instead.

Safety

It is up to the caller to ensure that the two ranges are in-bounds, that the two ranges don't overlap, and that the end of src is before the start.

Examples

Correct usage of this method:

let mut buffer = ConstBuffer::<u32, 10>::new();

unsafe {
    buffer.write(5, 10);
    buffer.write(7, 20);
    buffer.write(9, 30);

    buffer.copy_within_nonoverlapping(6.., 2);

    assert_eq!(buffer.read(3), 20);
    assert_eq!(buffer.read(5), 30);
    assert_eq!(buffer.read(7), 20);
    assert_eq!(buffer.read(9), 30);
}

Incorrect usage of this method:

let mut buffer = ConstBuffer::<u32, 10>::new();

// This will try to copy the elements from 4..8 to 2..6,
// which are overlapping ranges.
unsafe { buffer.copy_within(4..8, 2); }

pub unsafe fn copy_from_slice(&mut self, index: usize, slice: &[T])[src]

Copies the elements from the given slice into self, starting at position index.

Note that unlike slice::copy_from_slice, this method does not require that T implements Copy. It is your responsibility to make sure that this data can safely be duplicated. If not, consider using clone_from_slice instead.

Safety

It is up to the caller to ensure that the range the slice is copied to is in-bounds.

Examples

Correct usage of this method:

let mut buffer = ConstBuffer::<u32, 10>::new();

unsafe {
    buffer.copy_from_slice(3, &[1, 4]);
    assert_eq!(buffer.read(3), 1);
    assert_eq!(buffer.read(4), 4);
}

Incorrect usage of this method:

let vec = vec![vec![1, 2, 3], vec![4, 5, 6]];
let mut buffer = ConstBuffer::<Vec<u32>, 10>::new();

unsafe {
    buffer.copy_from_slice(3, &vec);
    let x = buffer.read(4);
    // The drop handler of `x` is executed here, which
    // frees the vector's memory and has `vec[1]` pointing
    // to garbage memory as a result.
}

pub unsafe fn clone_from_slice(&mut self, index: usize, slice: &[T]) where
    T: Clone
[src]

Clones the elements from the given slice into self, starting at position index.

Safety

It is up to the caller to ensure that the range the slice is copied to is in-bounds.

Examples

let vec = vec![vec![1, 2, 3], vec![4, 5, 6]];
let mut buffer = ConstBuffer::<Vec<u32>, 10>::new();

unsafe {
    buffer.clone_from_slice(3, &vec);
    let mut x = buffer.read(4);

    // `x` is a clone of `vec[1]`, so this will no affect the
    // original vector.
    x.reverse();
    assert_eq!(x, &[6, 5, 4]);
}

assert_eq!(vec[1], &[4, 5, 6]);

pub fn as_maybe_uninit_slice(&self) -> &[MaybeUninit<T>][src]

Returns a MaybeUninit slice to the buffer. Useful when you want to read MaybeUninit<T> values that may or may not be in an initialized state.

Examples

let mut buffer = ConstBuffer::<u32, 10>::new();

unsafe {
    buffer.write(4, 1);
    buffer.write(6, 3);

    let slice = &buffer.as_maybe_uninit_slice()[3..];
    assert_eq!(slice[1].assume_init(), 1);
    assert_eq!(slice[3].assume_init(), 3);
}

pub fn as_maybe_uninit_mut_slice(&mut self) -> &mut [MaybeUninit<T>][src]

Returns a mutable MaybeUninit slice to the buffer. Useful when you want to write MaybeUninit<T> values that may or may not be in an initialized state.

Examples

use std::mem::MaybeUninit;

let mut buffer = ConstBuffer::<u32, 10>::new();

unsafe {
    let slice = &mut buffer.as_maybe_uninit_mut_slice()[3..];
    slice[1] = MaybeUninit::new(1);
    slice[3] = MaybeUninit::new(3);

    assert_eq!(buffer.read(4), 1);
    assert_eq!(buffer.read(6), 3);
}

Trait Implementations

impl<T, const N: usize> Clone for ConstBuffer<T, N>[src]

fn clone(&self) -> Self[src]

Returns a copy of the buffer.

Note that this simply copies the bytes of the original buffer to the new buffer, and it does not call clone on any of the elements in the buffer. Therefore, if you end up reading the same element from both buffers, it is your responsibility to ensure that that data may indeed be duplicated.

If you want clone to be called on the elements in the buffer, consider using clone_from_slice instead.

impl<T, const N: usize> Debug for ConstBuffer<T, N>[src]

impl<T, const N: usize> Default for ConstBuffer<T, N>[src]

fn default() -> Self[src]

Creates an empty buffer.

impl<T, const N: usize> From<[MaybeUninit<T>; N]> for ConstBuffer<T, N>[src]

impl<T, const N: usize> From<[T; N]> for ConstBuffer<T, N>[src]

impl<T, const N: usize> From<MaybeUninit<[T; N]>> for ConstBuffer<T, N>[src]

Auto Trait Implementations

impl<const N: usize, T> Send for ConstBuffer<T, N> where
    T: Send

impl<const N: usize, T> Sync for ConstBuffer<T, N> where
    T: Sync

impl<const N: usize, T> Unpin for ConstBuffer<T, N> where
    T: Unpin

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.