swap_buffer_queue/buffer.rs
1//! [`Buffer`] definition and simple implementations.
2
3use core::{
4 fmt,
5 iter::FusedIterator,
6 marker::PhantomData,
7 mem::ManuallyDrop,
8 ops::{Deref, DerefMut, Range},
9 ptr,
10};
11
12use crate::queue::Queue;
13
14mod array;
15#[cfg(feature = "alloc")]
16mod vec;
17
18pub use array::ArrayBuffer;
19#[cfg(feature = "alloc")]
20pub use vec::VecBuffer;
21
22/// [`Queue`] buffer. It is used together with [`InsertIntoBuffer`].
23///
24/// # Safety
25/// [`Buffer::clear`] *clears* the inserted range from the buffer
26/// (see [`InsertIntoBuffer::insert_into`]), meaning new values can be inserted.
27pub unsafe trait Buffer: Default {
28 /// The slice type returned by [`slice`](Buffer::slice) method.
29 type Slice<'a>
30 where
31 Self: 'a;
32 /// Returns the buffer's capacity.
33 fn capacity(&self) -> usize;
34 /// Returns a slice of the buffer.
35 ///
36 /// # Safety
37 /// Range **must** have been inserted (see [`InsertIntoBuffer::insert_into`]) before calling
38 /// this method.
39 unsafe fn slice(&mut self, range: Range<usize>) -> Self::Slice<'_>;
40 /// Clears the buffer.
41 ///
42 /// # Safety
43 /// Range **must** have been inserted (see [`InsertIntoBuffer::insert_into`]) before calling
44 /// this method.
45 ///
46 /// Calling this method *clears* the inserted value, meaning new values can be inserted.
47 unsafe fn clear(&mut self, range: Range<usize>);
48}
49
50/// [`Buffer`] value.
51///
52/// # Safety
53/// Range `index..index+value.size()` is considered inserted into the buffer after calling
54/// [`InsertIntoBuffer::insert_into`] (see [`Buffer::slice`]/[`Buffer::clear`])
55pub unsafe trait InsertIntoBuffer<B: Buffer> {
56 /// Returns the size taken by a value in the buffer.
57 fn size(&self) -> usize;
58 /// Inserts the value into the buffer at the given index.
59 ///
60 /// # Safety
61 /// For every call to this method, the inserted range `index..index+self.size()` **must not**
62 /// overlap with a previously inserted one.
63 unsafe fn insert_into(self, buffer: &B, index: usize);
64}
65
66/// [`Buffer`] kind where value are inserted one by one.
67///
68/// # Safety
69/// `index` is considered inserted into the buffer after calling [`CellBuffer::insert`] (see [`Buffer::slice`]/[`Buffer::clear`])
70pub(crate) unsafe trait CellBuffer<T>: Buffer {
71 /// Inserts a value into the buffer at the given index.
72 ///
73 /// # Safety
74 /// For every call to this method, `index` **must not** have previously been inserted.
75 unsafe fn insert(&self, index: usize, value: T);
76}
77
78/// Wrapper to implement [`InsertIntoBuffer`] on iterators.
79pub struct ValueIter<I>(pub I);
80
81/// Extension trait to instantiate [`ValueIter`].
82pub trait IntoValueIter: Sized {
83 /// Iterator type to be wrapped in [`ValueIter`].
84 type Iter;
85 /// Wrap iterator into [`ValueIter`].
86 fn into_value_iter(self) -> ValueIter<Self::Iter>;
87}
88
89impl<I> IntoValueIter for I
90where
91 I: IntoIterator,
92 I::IntoIter: ExactSizeIterator,
93{
94 type Iter = I::IntoIter;
95 fn into_value_iter(self) -> ValueIter<Self::Iter> {
96 ValueIter(self.into_iter())
97 }
98}
99
100// SAFETY: `insert_into` does initialize the slice in the buffer
101unsafe impl<B, I, T> InsertIntoBuffer<B> for ValueIter<I>
102where
103 B: CellBuffer<T>,
104 I: Iterator<Item = T> + ExactSizeIterator,
105{
106 #[inline]
107 fn size(&self) -> usize {
108 self.0.len()
109 }
110
111 #[inline]
112 unsafe fn insert_into(mut self, buffer: &B, index: usize) {
113 // don't loop on iterator, because `ExactSizeIterator` is not a sufficient guarantee
114 // for unsafe code
115 for i in index..(index + self.0.len()) {
116 const ERROR: &str = "iterator exhausted before reaching its exact size";
117 // SAFETY: function contract encompass `CellBuffer::insert` one
118 unsafe { buffer.insert(i, self.0.next().expect(ERROR)) };
119 }
120 }
121}
122
123// SAFETY: `insert_into` does initialize the slice in the buffer
124unsafe impl<B, T, const N: usize> InsertIntoBuffer<B> for [T; N]
125where
126 B: CellBuffer<T>,
127{
128 #[inline]
129 fn size(&self) -> usize {
130 N
131 }
132
133 #[inline]
134 unsafe fn insert_into(self, buffer: &B, index: usize) {
135 for (i, elt) in self.into_iter().enumerate() {
136 // SAFETY: function contract encompass `CellBuffer::insert` one
137 unsafe { buffer.insert(index + i, elt) };
138 }
139 }
140}
141
142/// Resizable [`Buffer`].
143pub trait Resize: Buffer {
144 /// Resizes the buffer.
145 fn resize(&mut self, capacity: usize);
146}
147
148/// [`Buffer`] whose values can be drained from.
149///
150/// # Safety
151/// Calling [`Drain::remove`] remove the value inserted at index `index
152/// (see [`InsertIntoBuffer::insert_into`])
153pub unsafe trait Drain: Buffer {
154 /// Value to be removed from the buffer
155 type Value;
156 /// Removes a value from the buffer at a given index and return it.
157 ///
158 /// # Safety
159 /// A value **must** have been inserted at this index (see [`InsertIntoBuffer::insert_into`])
160 /// before calling this method.
161 unsafe fn remove(&mut self, index: usize) -> Self::Value;
162}
163
164/// [`Buffer`] slice returned by [`Queue::try_dequeue`] (see [`Buffer::Slice`]).
165///
166/// Buffer is released when the slice is dropped, so the other buffer will be dequeued next,
167/// unless [`BufferSlice::requeue`]/[`BufferSlice::into_iter`] is called.
168///
169/// # Examples
170/// ```
171/// # use std::ops::Deref;
172/// # use swap_buffer_queue::Queue;
173/// # use swap_buffer_queue::buffer::VecBuffer;
174/// let queue: Queue<VecBuffer<usize>> = Queue::with_capacity(42);
175/// queue.try_enqueue([0]).unwrap();
176/// queue.try_enqueue([1]).unwrap();
177///
178/// let slice = queue.try_dequeue().unwrap();
179/// assert_eq!(slice.deref(), &[0, 1]);
180/// assert_eq!(slice.into_iter().collect::<Vec<_>>(), vec![0, 1]);
181/// ```
182pub struct BufferSlice<'a, B, N>
183where
184 B: Buffer,
185{
186 queue: &'a Queue<B, N>,
187 buffer_index: usize,
188 range: Range<usize>,
189 slice: B::Slice<'a>,
190}
191
192impl<'a, B, N> BufferSlice<'a, B, N>
193where
194 B: Buffer,
195{
196 #[inline]
197 pub(crate) fn new(
198 queue: &'a Queue<B, N>,
199 buffer_index: usize,
200 range: Range<usize>,
201 slice: B::Slice<'a>,
202 ) -> Self {
203 Self {
204 queue,
205 buffer_index,
206 range,
207 slice,
208 }
209 }
210
211 /// Reinsert the buffer at the beginning queue.
212 ///
213 /// It will thus de dequeued again next.
214 ///
215 /// # Examples
216 /// ```
217 /// # use std::ops::Deref;
218 /// # use swap_buffer_queue::Queue;
219 /// # use swap_buffer_queue::buffer::VecBuffer;
220 /// let queue: Queue<VecBuffer<usize>> = Queue::with_capacity(42);
221 /// queue.try_enqueue([0]).unwrap();
222 /// queue.try_enqueue([1]).unwrap();
223 ///
224 /// let slice = queue.try_dequeue().unwrap();
225 /// assert_eq!(slice.deref(), &[0, 1]);
226 /// slice.requeue();
227 /// let slice = queue.try_dequeue().unwrap();
228 /// assert_eq!(slice.deref(), &[0, 1]);
229 /// ```
230 #[inline]
231 pub fn requeue(self) {
232 let slice = ManuallyDrop::new(self);
233 slice.queue.requeue(slice.buffer_index, slice.range.clone());
234 }
235}
236
237impl<'a, B, N> fmt::Debug for BufferSlice<'a, B, N>
238where
239 B: Buffer,
240 B::Slice<'a>: fmt::Debug,
241{
242 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
243 f.debug_tuple("BufferSlice").field(&self.slice).finish()
244 }
245}
246
247impl<'a, B, N> Deref for BufferSlice<'a, B, N>
248where
249 B: Buffer,
250{
251 type Target = B::Slice<'a>;
252
253 #[inline]
254 fn deref(&self) -> &Self::Target {
255 &self.slice
256 }
257}
258
259impl<'a, B, N> DerefMut for BufferSlice<'a, B, N>
260where
261 B: Buffer,
262{
263 #[inline]
264 fn deref_mut(&mut self) -> &mut Self::Target {
265 &mut self.slice
266 }
267}
268
269impl<'a, B, N> Drop for BufferSlice<'a, B, N>
270where
271 B: Buffer,
272{
273 #[inline]
274 fn drop(&mut self) {
275 self.queue.release(self.buffer_index, self.range.clone());
276 }
277}
278
279impl<'a, B, N> IntoIterator for BufferSlice<'a, B, N>
280where
281 B: Buffer + Drain,
282{
283 type Item = B::Value;
284 type IntoIter = BufferIter<'a, B, N>;
285
286 #[inline]
287 fn into_iter(self) -> Self::IntoIter {
288 let slice = ManuallyDrop::new(self);
289 BufferIter {
290 queue: slice.queue,
291 buffer_index: slice.buffer_index,
292 range: slice.range.clone(),
293 _phantom: PhantomData,
294 }
295 }
296}
297
298/// [`Buffer`] iterator returned by [`BufferSlice::into_iter`] (see [`Drain`]).
299///
300/// Buffer is lazily drained, and requeued (see [`BufferSlice::requeue`]) if the iterator is dropped while non exhausted.
301///
302/// # Examples
303/// ```
304/// # use std::ops::Deref;
305/// # use swap_buffer_queue::Queue;
306/// # use swap_buffer_queue::buffer::VecBuffer;
307/// let queue: Queue<VecBuffer<usize>> = Queue::with_capacity(42);
308/// queue.try_enqueue([0]).unwrap();
309/// queue.try_enqueue([1]).unwrap();
310///
311/// let mut iter = queue.try_dequeue().unwrap().into_iter();
312/// assert_eq!(iter.next(), Some(0));
313/// drop(iter);
314/// let mut iter = queue.try_dequeue().unwrap().into_iter();
315/// assert_eq!(iter.next(), Some(1));
316/// assert_eq!(iter.next(), None);
317/// ```
318pub struct OwnedBufferIter<Q, B, N>
319where
320 Q: AsRef<Queue<B, N>>,
321 B: Buffer,
322{
323 queue: Q,
324 buffer_index: usize,
325 range: Range<usize>,
326 _phantom: PhantomData<Queue<B, N>>,
327}
328
329/// Alias of [`OwnedBufferIter`] with a queue reference.
330pub type BufferIter<'a, B, N> = OwnedBufferIter<&'a Queue<B, N>, B, N>;
331
332impl<'a, B, N> BufferIter<'a, B, N>
333where
334 B: Buffer,
335{
336 /// Convert back a buffer iterator into a buffer slice.
337 ///
338 /// # Examples
339 /// ```
340 /// # use std::ops::Deref;
341 /// # use std::sync::Arc;
342 /// # use swap_buffer_queue::Queue;
343 /// # use swap_buffer_queue::buffer::VecBuffer;
344 /// let queue: Arc<Queue<VecBuffer<usize>>> = Arc::new(Queue::with_capacity(42));
345 /// queue.try_enqueue([0]).unwrap();
346 /// queue.try_enqueue([1]).unwrap();
347 ///
348 /// let iter = queue.try_dequeue().unwrap().into_iter();
349 /// let slice = iter.into_slice();
350 /// assert_eq!(slice.deref(), &[0, 1]);
351 /// ```
352 #[inline]
353 pub fn into_slice(self) -> BufferSlice<'a, B, N> {
354 let iter = ManuallyDrop::new(self);
355 BufferSlice {
356 queue: iter.queue,
357 buffer_index: iter.buffer_index,
358 range: iter.range.clone(),
359 slice: iter.queue.get_slice(iter.buffer_index, iter.range.clone()),
360 }
361 }
362}
363
364impl<Q, B, N> OwnedBufferIter<Q, B, N>
365where
366 Q: AsRef<Queue<B, N>>,
367 B: Buffer,
368{
369 /// Returns a "owned" version of the buffer iterator using a "owned" version of the queue.
370 ///
371 /// # Examples
372 /// ```
373 /// # use std::ops::Deref;
374 /// # use std::sync::Arc;
375 /// # use swap_buffer_queue::Queue;
376 /// # use swap_buffer_queue::buffer::VecBuffer;
377 /// let queue: Arc<Queue<VecBuffer<usize>>> = Arc::new(Queue::with_capacity(42));
378 /// queue.try_enqueue([0]).unwrap();
379 /// queue.try_enqueue([1]).unwrap();
380 ///
381 /// let mut iter = queue
382 /// .try_dequeue()
383 /// .unwrap()
384 /// .into_iter()
385 /// .with_owned(queue.clone());
386 /// drop(queue); // iter is "owned", queue can be dropped
387 /// assert_eq!(iter.next(), Some(0));
388 /// assert_eq!(iter.next(), Some(1));
389 /// assert_eq!(iter.next(), None);
390 /// ```
391 #[inline]
392 pub fn with_owned<O>(self, queue: O) -> OwnedBufferIter<O, B, N>
393 where
394 O: AsRef<Queue<B, N>>,
395 {
396 let iter = ManuallyDrop::new(self);
397 assert!(
398 ptr::eq(iter.queue.as_ref(), queue.as_ref()),
399 "new owner must reference the queue referenced by the iterator"
400 );
401 OwnedBufferIter {
402 queue,
403 buffer_index: iter.buffer_index,
404 range: iter.range.clone(),
405 _phantom: PhantomData,
406 }
407 }
408}
409
410impl<Q, B, N> fmt::Debug for OwnedBufferIter<Q, B, N>
411where
412 Q: AsRef<Queue<B, N>>,
413 B: Buffer,
414{
415 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
416 f.debug_tuple("BufferIter").field(&self.range).finish()
417 }
418}
419
420impl<Q, B, N> Drop for OwnedBufferIter<Q, B, N>
421where
422 Q: AsRef<Queue<B, N>>,
423 B: Buffer,
424{
425 #[inline]
426 fn drop(&mut self) {
427 self.queue
428 .as_ref()
429 .requeue(self.buffer_index, self.range.clone());
430 }
431}
432
433impl<Q, B, N> Iterator for OwnedBufferIter<Q, B, N>
434where
435 Q: AsRef<Queue<B, N>>,
436 B: Buffer + Drain,
437{
438 type Item = B::Value;
439
440 #[inline]
441 fn next(&mut self) -> Option<Self::Item> {
442 if self.range.is_empty() {
443 return None;
444 }
445 let value = self
446 .queue
447 .as_ref()
448 .remove(self.buffer_index, self.range.start);
449 self.range.start += 1;
450 Some(value)
451 }
452
453 #[inline]
454 fn size_hint(&self) -> (usize, Option<usize>) {
455 self.range.size_hint()
456 }
457}
458
459impl<Q, B, N> ExactSizeIterator for OwnedBufferIter<Q, B, N>
460where
461 Q: AsRef<Queue<B, N>>,
462 B: Buffer + Drain,
463{
464}
465
466impl<Q, B, N> FusedIterator for OwnedBufferIter<Q, B, N>
467where
468 Q: AsRef<Queue<B, N>>,
469 B: Buffer + Drain,
470{
471}