110: Add Queue::peek. r=japaric a=jmgao



Co-authored-by: Josh Gao <josh@jmgao.dev>
This commit is contained in:
bors[bot] 2019-08-28 13:49:27 +00:00 committed by GitHub
commit 03b890f161
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 73 additions and 0 deletions

View File

@ -117,6 +117,10 @@ where
U: sealed::Uxx,
C: sealed::XCore,
{
fn get(&self) -> &U {
unsafe { &*self.v.get() }
}
fn get_mut(&mut self) -> &mut U {
unsafe { &mut *self.v.get() }
}
@ -341,6 +345,40 @@ macro_rules! impl_ {
N: ArrayLength<T>,
C: sealed::XCore,
{
/// Returns a reference to the item in the front of the queue without dequeuing, or
/// `None` if the queue is empty.
///
/// # Examples
/// ```
/// use heapless::spsc::Queue;
/// use heapless::consts::*;
///
/// let mut queue: Queue<u8, U235, _> = Queue::u8();
/// let (mut producer, mut consumer) = queue.split();
/// assert_eq!(None, consumer.peek());
/// producer.enqueue(1);
/// assert_eq!(Some(&1), consumer.peek());
/// assert_eq!(Some(1), consumer.dequeue());
/// assert_eq!(None, consumer.peek());
/// ```
pub fn peek(&self) -> Option<&T> {
let cap = self.capacity();
let head = self.0.head.get();
let tail = self.0.tail.get();
let p = self.0.buffer.as_ptr();
if *head != *tail {
let item = unsafe {
&*(p as *const T).add(usize::from(*head % cap))
};
Some(item)
} else {
None
}
}
/// Returns the item in the front of the queue, or `None` if the queue is empty
pub fn dequeue(&mut self) -> Option<T> {
let cap = self.capacity();

View File

@ -84,6 +84,32 @@ macro_rules! impl_ {
return head != tail;
}
/// Returns the item in the front of the queue without dequeuing, or `None` if the queue is empty.
///
/// # Examples
/// ```
/// use heapless::spsc::Queue;
/// use heapless::consts::*;
///
/// let mut queue: Queue<u8, U235, _> = Queue::u8();
/// let (mut producer, mut consumer) = queue.split();
/// assert_eq!(None, consumer.peek());
/// producer.enqueue(1);
/// assert_eq!(Some(&1), consumer.peek());
/// assert_eq!(Some(1), consumer.dequeue());
/// assert_eq!(None, consumer.peek());
/// ```
pub fn peek(&self) -> Option<&T> {
let head = unsafe { self.rb.as_ref().0.head.load_relaxed() };
let tail = unsafe { self.rb.as_ref().0.tail.load_acquire() };
if head != tail {
Some(unsafe { self._peek(head) })
} else {
None
}
}
/// Returns the item in the front of the queue, or `None` if the queue is empty
pub fn dequeue(&mut self) -> Option<T> {
let head = unsafe { self.rb.as_ref().0.head.load_relaxed() };
@ -107,6 +133,15 @@ macro_rules! impl_ {
self._dequeue(head) // ▲
}
unsafe fn _peek(&self, head: $uxx) -> &T {
let rb = self.rb.as_ref();
let cap = rb.capacity();
let item = (rb.0.buffer.as_ptr() as *const T).add(usize::from(head % cap));
&*item
}
unsafe fn _dequeue(&mut self, head: $uxx) -> T {
let rb = self.rb.as_ref();