[−][src]Struct const_buffer::ConstBuffer
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]
I: BufferIndex<'a, T>,
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]
I: BufferIndex<'a, T>,
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]
R: RangeBounds<usize>,
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]
R: RangeBounds<usize>,
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]
T: Clone,
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.
fn clone_from(&mut self, source: &Self)
[src]
impl<T, const N: usize> Debug for ConstBuffer<T, N>
[src]
impl<T, const N: usize> Default for ConstBuffer<T, N>
[src]
impl<T, const N: usize> From<[MaybeUninit<T>; N]> for ConstBuffer<T, N>
[src]
fn from(array: [MaybeUninit<T>; N]) -> Self
[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]
fn from(maybe_uninit: MaybeUninit<[T; N]>) -> Self
[src]
Auto Trait Implementations
impl<const N: usize, T> Send for ConstBuffer<T, N> where
T: Send,
T: Send,
impl<const N: usize, T> Sync for ConstBuffer<T, N> where
T: Sync,
T: Sync,
impl<const N: usize, T> Unpin for ConstBuffer<T, N> where
T: Unpin,
T: Unpin,
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,