pub struct Page<H, T>(/* private fields */);
Expand description
An owned, heap-backed, dynamically-sized data page comprising a user-chosen
header and data array packed into a single allocation. It is an owned object and
the internal representation is a [NonNull
].
§Example
use pages::Page;
use core::mem::MaybeUninit;
// A really crappy replacement for Box<Option<usize>>
struct Maybe(Page::<bool, usize>);
impl Maybe {
fn new() -> Self { Maybe(Page::new(false, 1)) }
fn put(&mut self, value: usize) {
*self.0.header_mut() = true; // occupied
unsafe { self.0.data().write(MaybeUninit::new(value)) };
}
fn get(&mut self) -> Option<usize> {
if !(*self.0.header()) { return None; }
*self.0.header_mut() = false; // free
Some(unsafe { self.0.data().read().assume_init() })
}
}
let mut maybe = Maybe::new();
assert_eq!(maybe.get(), None);
maybe.put(42);
assert_eq!(maybe.get(), Some(42));
§Notes
Data is exposed as a MaybeUninit
pointer for maximum flexibility.
Unfortunately this means we’re unable to automatically drop the data
for you in our destructor. You could cause a memory leak if you don’t.
Implementations§
Source§impl<H, T> Page<H, T>
impl<H, T> Page<H, T>
Sourcepub fn header_mut(&mut self) -> &mut H
pub fn header_mut(&mut self) -> &mut H
Access to this page’s header by mut reference.
Sourcepub fn data(&self) -> *mut MaybeUninit<T>
pub fn data(&self) -> *mut MaybeUninit<T>
Access to the start of the data array as a mut pointer.
Sourcepub fn layout(&self) -> PageLayout<H, T>
pub fn layout(&self) -> PageLayout<H, T>
Returns the PageLayout
describing the memory layout of this Page
Sourcepub unsafe fn from_uninit(
raw_ptr: *mut u8,
header: H,
layout: PageLayout<H, T>,
) -> Self
pub unsafe fn from_uninit( raw_ptr: *mut u8, header: H, layout: PageLayout<H, T>, ) -> Self
Creates a new Page
from a pointer to uninitialised memory, a header and
a PageLayout
.
§Safety
You must ensure:
- The pointer was allocated according to the provided
PageLayout
.- Synchronise all reads and writes to
- Suppress the destructor of all but one of them (e.g. by wrapping in [
ManuallyDrop
]).
- If the pointer did not originate from the global allocator, you must
suppress the destructor (e.g. by wrapping in [
ManuallyDrop
]).
Trait Implementations§
impl<H: Send, T: Send> Send for Page<H, T>
impl<H: Sync, T: Sync> Sync for Page<H, T>
Auto Trait Implementations§
impl<H, T> Freeze for Page<H, T>
impl<H, T> RefUnwindSafe for Page<H, T>where
H: RefUnwindSafe,
T: RefUnwindSafe,
impl<H, T> Unpin for Page<H, T>
impl<H, T> UnwindSafe for Page<H, T>where
H: UnwindSafe,
T: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more