volatile/volatile_ptr/mod.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
use core::{fmt, marker::PhantomData, ptr::NonNull};
use crate::{access::ReadWrite, ops::VolatileOps};
mod macros;
mod operations;
#[cfg(test)]
mod tests;
#[cfg(feature = "unstable")]
mod unstable;
#[cfg(feature = "very_unstable")]
mod very_unstable;
/// Wraps a pointer to make accesses to the referenced value volatile.
///
/// Allows volatile reads and writes on the referenced value. The referenced value needs to
/// be `Copy` for reading and writing, as volatile reads and writes take and return copies
/// of the value.
///
/// Since not all volatile resources (e.g. memory mapped device registers) are both readable
/// and writable, this type supports limiting the allowed access types through an optional second
/// generic parameter `A` that can be one of `ReadWrite`, `ReadOnly`, or `WriteOnly`. It defaults
/// to `ReadWrite`, which allows all operations.
///
/// The size of this struct is the same as the size of the contained reference.
#[repr(transparent)]
pub struct VolatilePtr<'a, T, A = ReadWrite, O = VolatileOps>
where
T: ?Sized,
{
pointer: NonNull<T>,
reference: PhantomData<&'a T>,
access: PhantomData<A>,
ops: PhantomData<O>,
}
impl<'a, T, A, O> Copy for VolatilePtr<'a, T, A, O> where T: ?Sized {}
impl<T, A, O> Clone for VolatilePtr<'_, T, A, O>
where
T: ?Sized,
{
fn clone(&self) -> Self {
*self
}
}
impl<T, A, O> fmt::Debug for VolatilePtr<'_, T, A, O>
where
T: ?Sized,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("VolatilePtr")
.field("pointer", &self.pointer)
.field("access", &self.access)
.finish()
}
}