reusable_memory/borrow/
mod.rs

1use std::{
2	borrow::{Borrow, BorrowMut},
3	marker::PhantomData,
4	mem,
5	num::NonZeroUsize,
6	ops::{Deref, DerefMut, RangeBounds},
7	ptr
8};
9
10pub mod drain;
11mod manual_specialization;
12
13pub use drain::BorrowDrainIter;
14
15#[derive(Debug, Copy, Clone)]
16pub enum ReusableMemoryBorrowError {
17	NotEnoughCapacity(NonZeroUsize)
18}
19impl std::fmt::Display for ReusableMemoryBorrowError {
20	fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
21		match self {
22			ReusableMemoryBorrowError::NotEnoughCapacity(capacity) => {
23				write!(f, "Not enough capacity ({}) to push another element.", capacity)
24			}
25		}
26	}
27}
28impl std::error::Error for ReusableMemoryBorrowError {
29	fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
30}
31
32/// Borrow of the reusable memory.
33///
34/// This struct borrows a properly aligned subset of the memory owned by `ReusableMemory`.
35///
36/// This structs semantically acts as `&'mem mut [T]` for variance, `Send` and `Sync` purposes.
37pub struct ReusableMemoryBorrow<'mem, T> {
38	// This could be `*mut T`, but we know it can't be null.
39	memory: ptr::NonNull<T>,
40	len: usize,
41	capacity: NonZeroUsize,
42
43	// We don't own the memory, we just mutably borrowed it.
44	boo: PhantomData<&'mem mut [T]>
45}
46impl<'mem, T> ReusableMemoryBorrow<'mem, T> {
47	/// Constructs memory borrow from raw parts.
48	///
49	/// ### Safety
50	///
51	/// * memory must be a valid pointer into `capacity * size_of::<T>()` bytes of memory.
52	pub unsafe fn from_raw_parts(memory: ptr::NonNull<T>, capacity: NonZeroUsize) -> Self {
53		ReusableMemoryBorrow { memory, len: 0, capacity, boo: PhantomData }
54	}
55
56	/// Returns number of `T`s currently stored.
57	pub const fn len(&self) -> usize { self.len }
58
59	/// Returns number of `T`s currently stored.
60	pub unsafe fn set_len(&mut self, len: usize) { self.len = len; }
61
62	/// Returns number of `T`s that can be stored.
63	pub const fn capacity(&self) -> NonZeroUsize { self.capacity }
64
65	/// Returns a const pointer to the data.
66	pub const fn as_ptr(&self) -> *const T { self.memory.as_ptr() as *const _ }
67
68	/// Returns a mut pointer to the data.
69	pub const fn as_mut_ptr(&self) -> *mut T { self.memory.as_ptr() }
70
71	/// Returns a slice view of the data.
72	pub fn as_slice(&self) -> &[T] {
73		unsafe { std::slice::from_raw_parts(self.as_ptr(), self.len()) }
74	}
75
76	/// Returns a mut slice view of the data.
77	pub fn as_mut_slice(&mut self) -> &mut [T] {
78		unsafe { std::slice::from_raw_parts_mut(self.as_ptr() as *mut _, self.len()) }
79	}
80
81	/// Drops all pushed values and sets the length to 0.
82	pub fn clear(&mut self) {
83		if mem::needs_drop::<T>() {
84			unsafe {
85				let mut ptr = self.memory.as_ptr().add(self.len);
86				let current_len = self.len;
87				// Panic safety, rather leak than double-drop.
88				// Vec uses internal `SetLenOnDrop` but this is okay too.
89				self.len = 0;
90
91				for _ in 0 .. current_len {
92					ptr = ptr.offset(-1);
93					ptr::drop_in_place(ptr);
94				}
95			}
96		} else {
97			self.len = 0;
98		}
99	}
100
101	/// Pushes a new value.
102	///
103	/// Returns Err if there is not enough capacity.
104	pub fn push(&mut self, value: T) -> Result<(), ReusableMemoryBorrowError> {
105		if self.len == self.capacity.get() {
106			return Err(ReusableMemoryBorrowError::NotEnoughCapacity(self.capacity))
107		}
108
109		unsafe {
110			let dst = self.memory.as_ptr().add(self.len);
111			ptr::write(dst, value);
112
113			self.len += 1;
114		}
115
116		Ok(())
117	}
118
119	/// Pops from the end.
120	///
121	/// Returns `None` if `self.len() == 0`.
122	pub fn pop(&mut self) -> Option<T> {
123		if self.len() == 0 {
124			return None
125		}
126
127		let value = unsafe {
128			self.len -= 1;
129			ptr::read(self.memory.as_ptr().add(self.len))
130		};
131
132		Some(value)
133	}
134
135	/// Creates a draining iterator that removes the specified range in the borrow and yields the removed items.
136	///
137	/// This functions exactly as `Vec::drain`.
138	pub fn drain<'bor>(
139		&'bor mut self, range: impl RangeBounds<usize>
140	) -> BorrowDrainIter<'bor, 'mem, T> {
141		BorrowDrainIter::new(self, range)
142	}
143}
144impl<'mem, T> Deref for ReusableMemoryBorrow<'mem, T> {
145	type Target = [T];
146
147	fn deref(&self) -> &Self::Target { self.as_slice() }
148}
149impl<'mem, T> DerefMut for ReusableMemoryBorrow<'mem, T> {
150	fn deref_mut(&mut self) -> &mut Self::Target { self.as_mut_slice() }
151}
152impl<'mem, T> Borrow<[T]> for ReusableMemoryBorrow<'mem, T> {
153	fn borrow(&self) -> &[T] { self.as_slice() }
154}
155impl<'mem, T> BorrowMut<[T]> for ReusableMemoryBorrow<'mem, T> {
156	fn borrow_mut(&mut self) -> &mut [T] { self.as_mut_slice() }
157}
158impl<'mem, T> AsRef<[T]> for ReusableMemoryBorrow<'mem, T> {
159	fn as_ref(&self) -> &[T] { self.as_slice() }
160}
161impl<'mem, T> AsMut<[T]> for ReusableMemoryBorrow<'mem, T> {
162	fn as_mut(&mut self) -> &mut [T] { self.as_mut_slice() }
163}
164impl<'mem, T> Drop for ReusableMemoryBorrow<'mem, T> {
165	fn drop(&mut self) { self.clear(); }
166}
167impl<'mem, T: std::fmt::Debug> std::fmt::Debug for ReusableMemoryBorrow<'mem, T> {
168	fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
169		write!(f, "[{}/{}] {:?}", self.len, self.capacity, self.as_slice())
170	}
171}